From c20cc7d1ca185e05aaa704245628edd61ce6db91 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 26 Apr 2021 16:54:45 -0600 Subject: [PATCH 001/404] Store platform and orientation on PBIntermediateTree Added mixins that extract platform and orientation data that is assigned to PBGenerationViewData. Co-authored-by: Bryan Figueroa --- lib/controllers/controller.dart | 2 -- lib/controllers/interpret.dart | 11 +++++-- lib/controllers/utils/interpret_utils.dart | 32 +++++++++++++++++++ .../attribute-helper/pb_size_helper.dart | 18 +++++++---- .../util/pb_generation_view_data.dart | 14 ++++++++ 5 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 lib/controllers/utils/interpret_utils.dart diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index e1e7c45a..8ec7f291 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -36,8 +36,6 @@ abstract class Controller { var pbProject = await Interpret().interpretAndOptimize(designProject); - pbProject.forest.forEach((tree) => tree.data = PBGenerationViewData()); - await PreGenerationService( projectName: projectPath, mainTree: pbProject, diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 8c0f60ed..edd563e3 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -1,4 +1,6 @@ import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/controllers/utils/interpret_utils.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; import 'package:parabeac_core/input/helper/design_project.dart'; import 'package:parabeac_core/input/helper/design_page.dart'; @@ -20,7 +22,7 @@ import 'package:quick_log/quick_log.dart'; import 'main_info.dart'; -class Interpret { +class Interpret with InterpretUtils { var log = Logger('Interpret'); Interpret._internal(); @@ -77,8 +79,13 @@ class Interpret { var tempTree = currentScreen; tempTree.name = designPage.name; + tempTree.data = PBGenerationViewData(); if (currentScreen.rootNode is InheritedScaffold) { - tempTree.tree_type = TREE_TYPE.SCREEN; + tempTree.data.platform = extractPlatform(designPage.name); + + tempTree.data.orientation = extractOrientation( + tempTree.rootNode.bottomRightCorner, + tempTree.rootNode.topLeftCorner); } else if (currentScreen.rootNode is PBSharedMasterNode) { tempTree.tree_type = TREE_TYPE.VIEW; } else { diff --git a/lib/controllers/utils/interpret_utils.dart b/lib/controllers/utils/interpret_utils.dart new file mode 100644 index 00000000..39fc78a8 --- /dev/null +++ b/lib/controllers/utils/interpret_utils.dart @@ -0,0 +1,32 @@ +import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; +import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + +/// Utils that extract platform and orientation from a node. +mixin InterpretUtils { + /// Extracts and returns platform of the screen. + /// + /// Defaults to PLATFORM.MOBILE if no platform is given. + PLATFORM extractPlatform(String name) { + var platform = name?.split('/')?.last?.toLowerCase()?.trim() ?? ''; + switch (platform) { + case 'desktop': + return PLATFORM.DESKTOP; + case 'tablet': + return PLATFORM.TABLET; + default: + return PLATFORM.MOBILE; + } + } + + /// Extracts orientation based on a node's TLC and BRC points. + ORIENTATION extractOrientation(Point bottomRight, Point topLeft) { + var width = (topLeft.x - bottomRight.x).abs(); + var height = (topLeft.y - bottomRight.y).abs(); + + if (height < width) { + return ORIENTATION.HORIZONTAL; + } + + return ORIENTATION.VERTICAL; + } +} diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index 9282dc53..0a0dd416 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -20,13 +20,19 @@ class PBSizeHelper extends PBAttributesHelper { var body = source.size ?? {}; double height = body['height']; double width = body['width']; + //Add relative sizing if the widget has context - var screenWidth = ((source.currentContext.screenTopLeftCorner.x) - - (source.currentContext.screenBottomRightCorner.x)) - .abs(); - var screenHeight = ((source.currentContext.screenTopLeftCorner.y) - - (source.currentContext.screenBottomRightCorner.y)) - .abs(); + var screenWidth; + var screenHeight; + if (source.currentContext.screenTopLeftCorner != null && + source.currentContext.screenBottomRightCorner != null) { + screenWidth = ((source.currentContext.screenTopLeftCorner.x) - + (source.currentContext.screenBottomRightCorner.x)) + .abs(); + screenHeight = ((source.currentContext.screenTopLeftCorner.y) - + (source.currentContext.screenBottomRightCorner.y)) + .abs(); + } height = (height != null && screenHeight != null && screenHeight > 0.0) ? height / screenHeight diff --git a/lib/generation/generators/util/pb_generation_view_data.dart b/lib/generation/generators/util/pb_generation_view_data.dart index 509213fe..5061e983 100644 --- a/lib/generation/generators/util/pb_generation_view_data.dart +++ b/lib/generation/generators/util/pb_generation_view_data.dart @@ -9,6 +9,9 @@ class PBGenerationViewData { final Set _toDispose = {}; bool _isDataLocked = false; + PLATFORM platform; + ORIENTATION orientation; + PBGenerationViewData(); Iterator get toDispose => _toDispose.iterator; @@ -76,3 +79,14 @@ class PBGenerationViewData { } } } + +enum PLATFORM { + DESKTOP, + MOBILE, + TABLET, +} + +enum ORIENTATION { + HORIZONTAL, + VERTICAL, +} From e84aced02ed24d6e99154301aa84e250df5edfde Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 27 Apr 2021 16:21:23 -0600 Subject: [PATCH 002/404] Added PBPlatformOrientationLinkerService Moved interpret utils to PlatformOrientationLinkerService Co-authored-by: Bryan Figueroa Co-authored-by: Eduardo Herrera --- lib/controllers/interpret.dart | 10 +- lib/controllers/utils/interpret_utils.dart | 32 ---- .../util/pb_generation_view_data.dart | 12 +- .../services/pb_platform_linker_service.dart | 138 ++++++++++++++++++ 4 files changed, 142 insertions(+), 50 deletions(-) delete mode 100644 lib/controllers/utils/interpret_utils.dart create mode 100644 lib/interpret_and_optimize/services/pb_platform_linker_service.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index edd563e3..6a116419 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -1,5 +1,4 @@ import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/controllers/utils/interpret_utils.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; import 'package:parabeac_core/input/helper/design_project.dart'; @@ -14,6 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_visual_generation_service.dart'; @@ -22,7 +22,7 @@ import 'package:quick_log/quick_log.dart'; import 'main_info.dart'; -class Interpret with InterpretUtils { +class Interpret { var log = Logger('Interpret'); Interpret._internal(); @@ -81,11 +81,7 @@ class Interpret with InterpretUtils { tempTree.data = PBGenerationViewData(); if (currentScreen.rootNode is InheritedScaffold) { - tempTree.data.platform = extractPlatform(designPage.name); - - tempTree.data.orientation = extractOrientation( - tempTree.rootNode.bottomRightCorner, - tempTree.rootNode.topLeftCorner); + PBPlatformOrientationLinkerService().addOrientationPlatformInformation(tempTree); } else if (currentScreen.rootNode is PBSharedMasterNode) { tempTree.tree_type = TREE_TYPE.VIEW; } else { diff --git a/lib/controllers/utils/interpret_utils.dart b/lib/controllers/utils/interpret_utils.dart deleted file mode 100644 index 39fc78a8..00000000 --- a/lib/controllers/utils/interpret_utils.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; - -/// Utils that extract platform and orientation from a node. -mixin InterpretUtils { - /// Extracts and returns platform of the screen. - /// - /// Defaults to PLATFORM.MOBILE if no platform is given. - PLATFORM extractPlatform(String name) { - var platform = name?.split('/')?.last?.toLowerCase()?.trim() ?? ''; - switch (platform) { - case 'desktop': - return PLATFORM.DESKTOP; - case 'tablet': - return PLATFORM.TABLET; - default: - return PLATFORM.MOBILE; - } - } - - /// Extracts orientation based on a node's TLC and BRC points. - ORIENTATION extractOrientation(Point bottomRight, Point topLeft) { - var width = (topLeft.x - bottomRight.x).abs(); - var height = (topLeft.y - bottomRight.y).abs(); - - if (height < width) { - return ORIENTATION.HORIZONTAL; - } - - return ORIENTATION.VERTICAL; - } -} diff --git a/lib/generation/generators/util/pb_generation_view_data.dart b/lib/generation/generators/util/pb_generation_view_data.dart index 5061e983..2de965c1 100644 --- a/lib/generation/generators/util/pb_generation_view_data.dart +++ b/lib/generation/generators/util/pb_generation_view_data.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_linker_service.dart'; class PBGenerationViewData { final Map _globalVariables = {}; @@ -79,14 +80,3 @@ class PBGenerationViewData { } } } - -enum PLATFORM { - DESKTOP, - MOBILE, - TABLET, -} - -enum ORIENTATION { - HORIZONTAL, - VERTICAL, -} diff --git a/lib/interpret_and_optimize/services/pb_platform_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_linker_service.dart new file mode 100644 index 00000000..9c4865f7 --- /dev/null +++ b/lib/interpret_and_optimize/services/pb_platform_linker_service.dart @@ -0,0 +1,138 @@ +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + +class PBPlatformOrientationLinkerService { + static final PBPlatformOrientationLinkerService _pbPlatformLinkerService = + PBPlatformOrientationLinkerService._internal(); + + PBPlatformOrientationLinkerService._internal(); + + factory PBPlatformOrientationLinkerService() => _pbPlatformLinkerService; + + final Map> _map = {}; + + /// Set of all platforms in the project + final Set _platforms = {}; + + /// Set of all orientations in the project + final Set _orientations = {}; + + /// Populates [tree]'s platform and orientation information + /// and adds [tree] to storage. + void addOrientationPlatformInformation(PBIntermediateTree tree) { + tree.data.platform = _extractPlatform(tree.name); + tree.data.orientation = _extractOrientation( + tree.rootNode.bottomRightCorner, + tree.rootNode.topLeftCorner, + ); + + _platforms.add(tree.data.platform); + _orientations.add(tree.data.orientation); + + addToMap(tree); + } + + /// Adds [tree] to the storage + void addToMap(PBIntermediateTree tree) { + // TODO: check if we have exact trees (equal orientation and platform) + if (_map.containsKey(tree.name)) { + _map[tree.name].add(tree); + } else { + _map[tree.name] = [tree]; + } + } + + /// Returns the list of [PBIntermediateTree] with matching [name]. + List getScreensWithName(String name) { + if (_map.containsKey(name)) { + return _map[name]; + } + return []; + } + + /// Returns a map containing platform and orientation information for the screen with matching [name]. + /// + /// Below is an example output of this method: + /// { + /// PLATFORM.MOBILE: { + /// ORIENTATION.VERTICAL: PBINTERMEDIATETREE, + /// ORIENTATION.HORIZONTAL: PBINTERMEDIATETREE, + /// }, + /// PLATFORM.DESKTOP: { + /// ORIENTATION.HORIZONTAL: PBINTERMEDIATETREE, + /// } + /// } + Map> + getPlatformOrientationData(String name) { + var result = {}; + if (_map.containsKey(name)) { + var screens = _map[name]; + + for (var screen in screens) { + // Add orientation to a platform + if (result.containsKey(screen.data.platform)) { + result[screen.data.platform][screen.data.orientation] = screen; + } + // Create entry for current platform-orientation pair + else { + result[screen.data.platform] = { + screen.data.orientation: screen, + }; + } + } + } + return result; + } + + /// Returns [true] if any screen has support for more than + /// one platform. Returns [false] otherwise. + bool hasMultiplePlatforms() => _platforms.length > 1; + + /// returns [true] if any screen has support for more than + /// one orientation. Returns [false] otherwise. + bool hasMultipleOrientations() => _orientations.length > 1; + + /// Returns platforms of the project + Set get platforms => _platforms; + + /// Returns orientations of the project + Set get orientations => _orientations; + + /// Extracts and returns platform of the screen. + /// + /// Defaults to PLATFORM.MOBILE if no platform is given. + PLATFORM _extractPlatform(String name) { + var platform = name?.split('/')?.last?.toLowerCase()?.trim() ?? ''; + switch (platform) { + case 'desktop': + return PLATFORM.DESKTOP; + case 'tablet': + return PLATFORM.TABLET; + default: + return PLATFORM.MOBILE; + } + } + + /// Extracts orientation based on a node's TLC and BRC points. + ORIENTATION _extractOrientation(Point bottomRight, Point topLeft) { + var width = (topLeft.x - bottomRight.x).abs(); + var height = (topLeft.y - bottomRight.y).abs(); + + if (height < width) { + return ORIENTATION.HORIZONTAL; + } + + return ORIENTATION.VERTICAL; + } +} + +enum PLATFORM { + DESKTOP, + MOBILE, + TABLET, +} + +enum ORIENTATION { + HORIZONTAL, + VERTICAL, +} From 5b854b4e4ebbed2c4ec3064f24e4e3f7cb1a1e93 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 28 Apr 2021 16:25:29 -0600 Subject: [PATCH 003/404] Created SemiConstantTemplate class Co-authored-by: Bryan Figueroa --- .../semi_constant_template/semi_constant_template.dart | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 lib/generation/semi_constant_template/semi_constant_template.dart diff --git a/lib/generation/semi_constant_template/semi_constant_template.dart b/lib/generation/semi_constant_template/semi_constant_template.dart new file mode 100644 index 00000000..981f79f2 --- /dev/null +++ b/lib/generation/semi_constant_template/semi_constant_template.dart @@ -0,0 +1,3 @@ +abstract class SemiConstantTemplate { + String generateTemplate(); +} From 72fafafcbdc6bc041ca626614d86478fb0c5de42 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 28 Apr 2021 16:27:17 -0600 Subject: [PATCH 004/404] renamed `semi_constant_template` to `semi_constant_templates` --- .../semi_constant_template.dart | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/generation/{semi_constant_template => semi_constant_templates}/semi_constant_template.dart (100%) diff --git a/lib/generation/semi_constant_template/semi_constant_template.dart b/lib/generation/semi_constant_templates/semi_constant_template.dart similarity index 100% rename from lib/generation/semi_constant_template/semi_constant_template.dart rename to lib/generation/semi_constant_templates/semi_constant_template.dart From ba12c89454123f8e972990dc7575bb76f5a7de63 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 28 Apr 2021 17:08:44 -0600 Subject: [PATCH 005/404] Added orientation builder template --- .../orientation_builder_template.dart | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 lib/generation/semi_constant_templates/orientation_builder_template.dart diff --git a/lib/generation/semi_constant_templates/orientation_builder_template.dart b/lib/generation/semi_constant_templates/orientation_builder_template.dart new file mode 100644 index 00000000..c1e1d889 --- /dev/null +++ b/lib/generation/semi_constant_templates/orientation_builder_template.dart @@ -0,0 +1,48 @@ +import 'package:parabeac_core/generation/semi_constant_templates/semi_constant_template.dart'; + +class OrientationBuilderTemplate implements SemiConstantTemplate { + @override + String generateTemplate() { + return ''' + import 'package:flutter/material.dart'; + + class ResponsiveOrientationBuilder extends StatelessWidget { + final Widget verticalPage; + final Widget horizontalPage; + + const ResponsiveOrientationBuilder({ + this.verticalPage, + this.horizontalPage, + }); + + @override + Widget build(BuildContext context) { + return OrientationBuilder(builder: (context, orientation) { + switch (orientation) { + case Orientation.portrait: + return verticalPage; + break; + case Orientation.landscape: + return horizontalPage; + default: + return ErrorScreen(); + } + }); + } + } + + class ErrorScreen extends StatelessWidget { + // TODO: Change this screen to match your project + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: Text('Something went wrong!'), + ), + ); + } + } + + '''; + } +} From 8eae8b8244662beeab5e7d81496f8d4a89f35ef4 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 28 Apr 2021 19:29:39 -0600 Subject: [PATCH 006/404] Added ResponsiveLayoutBuilderTemplate --- .../responsive_layout_builder_template.dart | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 lib/generation/semi_constant_templates/responsive_layout_builder_template.dart diff --git a/lib/generation/semi_constant_templates/responsive_layout_builder_template.dart b/lib/generation/semi_constant_templates/responsive_layout_builder_template.dart new file mode 100644 index 00000000..3d49e4e7 --- /dev/null +++ b/lib/generation/semi_constant_templates/responsive_layout_builder_template.dart @@ -0,0 +1,76 @@ +import 'dart:collection'; + +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/semi_constant_templates/semi_constant_template.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_linker_service.dart'; + +class ResponsiveLayoutBuilderTemplate implements SemiConstantTemplate { + @override + String generateTemplate() { + var platforms = PBPlatformOrientationLinkerService() + .platforms + .map((platform) => platform.toString().split('.').last.toLowerCase()); + var widgetVars = _generatePlatformWidgets(platforms); + var widgetInit = _generatePlatformInitializers(platforms); + var breakpointChecks = _generateBreakpointStatements(platforms); + return ''' + class ResponsiveLayoutBuilder extends StatelessWidget { + ${widgetVars} + + const ResponsiveLayoutBuilder( + { + Key key, + ${widgetInit} + } + ); + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, constraints) { + var width = constraints.maxWidth; + ${breakpointChecks} + return Container(); + }, + ); + } + } + '''; + } + + String _generatePlatformWidgets(List platforms) { + var result = ''; + platforms.forEach((platform) => result += 'final ${platform}Widget;'); + return result; + } + + String _generatePlatformInitializers(List platforms) { + var result = ''; + platforms.forEach((platform) => result += 'this.${platform}Widget,'); + return result; + } + + String _generateBreakpointStatements(List platforms) { + if (platforms.length == 1) { + return 'if(${platforms[0]} != null){return ${platforms[0]}Widget;}'; + } + // Get breakpoints from configurations and sort by value + Map breakpoints = MainInfo().configurations['breakpoints']; + var sortedMap = SplayTreeMap.from( + breakpoints, (a, b) => breakpoints[a].compareTo(breakpoints[b])); + + var result = ''; + for (var i; i < platforms.length; i++) { + var platform = platforms[i]; + if (sortedMap.containsKey(platform)) { + if (i == platforms.length - 1) { + result += 'if(${platform}Widget != null){return ${platform}Widget;}'; + } else { + result += + 'if(${platform}Widget != null && width < ${platforms[i + 1]}Breakpoint) {return ${platform}Widget;}'; + } + } + } + return result; + } +} From c12ff8e4c512ea861e6af4b6f7e7e8efcf48f900 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 29 Apr 2021 16:25:02 -0600 Subject: [PATCH 007/404] Added Templates list to Generation Project Data --- .../util/pb_generation_project_data.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/generation/generators/util/pb_generation_project_data.dart b/lib/generation/generators/util/pb_generation_project_data.dart index 5700eb45..c20542e2 100644 --- a/lib/generation/generators/util/pb_generation_project_data.dart +++ b/lib/generation/generators/util/pb_generation_project_data.dart @@ -1,6 +1,20 @@ import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; +import 'package:parabeac_core/generation/semi_constant_templates/semi_constant_template.dart'; class PBGenerationProjectData { + // List of current templates on the project + List templates = []; + + // Add template to the project + // only if the template is not already part of + // current project's templates + void addTemplate(SemiConstantTemplate template) { + if (!templates + .any((element) => element.runtimeType == template.runtimeType)) { + templates.add(template); + } + } + void addDependencies(String packageName, String version) => PBFlutterWriter().addDependency(packageName, version); } From 8587905e0b1e0711cb78a835be28f2fe0b488ccf Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 29 Apr 2021 16:25:51 -0600 Subject: [PATCH 008/404] Linker can add templates to the project --- SketchAssetConverter | 2 +- TESTJSON/example.json | 33993 ++++++++++++++++ TESTJSON/temp.json | 1 + .../services/pb_platform_linker_service.dart | 15 + 4 files changed, 34010 insertions(+), 1 deletion(-) create mode 100644 TESTJSON/example.json create mode 100644 TESTJSON/temp.json diff --git a/SketchAssetConverter b/SketchAssetConverter index 1b5effbd..1b5f17f1 160000 --- a/SketchAssetConverter +++ b/SketchAssetConverter @@ -1 +1 @@ -Subproject commit 1b5effbd220ff03015bc4b288184005e4443f056 +Subproject commit 1b5f17f1dc78d907082eada8eaa79b820908eccf diff --git a/TESTJSON/example.json b/TESTJSON/example.json new file mode 100644 index 00000000..5f96886b --- /dev/null +++ b/TESTJSON/example.json @@ -0,0 +1,33993 @@ +{ + "projectName": "example", + "pbdfType": "project", + "id": "c056f644-e132-461b-84d6-9b3abcacfd0c", + "_class": "sharedStyle", + "do_objectID": "0848D478-81B0-415D-AC7C-FE13BE3A6BFD", + "name": "3Text3IndigoText116RightAlign", + "value": { + "_class": "style", + "do_objectID": "86774DC8-3409-4ECA-B674-E7E5E53BB974", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 5, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Regular", + "size": 16 + } + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "maximumLineHeight": 22, + "minimumLineHeight": 22, + "allowsDefaultTighteningForTruncation": 0, + "alignment": 1 + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.796078431372549, + "green": 0.1882352941176471, + "red": 0.5176470588235293 + }, + "kerning": -0.4000000059604645 + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pages": [ + { + "pbdfType": "design_page", + "id": "901e015d-2171-43ed-b8cd-8eedc5996b91", + "name": "Symbols", + "convert": true, + "screens": [ + { + "pbdfType": "screen", + "id": "a1ca9316-82b5-4270-b143-97575f0ec1d0", + "name": "SmallMajorCard", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Majors Overview", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + }, + "io.magicsketch.mirror": { + "highestQuality": -1 + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "header", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 375, + "x": 0, + "y": 0 + }, + "id": "3D096DF9-6442-4435-8B8F-E3AAC1B51E62", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "04DFC884-2240-4FD2-B69E-02C56B9BB460", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 0, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 375, + "x": 0, + "y": 0 + }, + "id": "D5F53318-78C2-443B-A0E4-62ED5644FEF6", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "3E99742C-458B-4E6B-88BE-8AA8CCE14BD6", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.207843137254902 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + }, + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.2078431372549019 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.2078431372549019 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "userScore", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 25, + "width": 70, + "x": 154, + "y": 51 + }, + "id": "8837475A-6727-4C29-82A4-F3412CE5687C", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4902C688-72C2-46D9-BA06-99C2FEAAF725", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "285", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "285", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 3, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 21 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 5}, {38, 16}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 25, + "width": 40, + "x": 0, + "y": 0 + }, + "id": "31FDA500-C98C-4383-B2B5-FC32759643F2", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4988E1EC-1EB3-4EAD-8B2B-4072F6495D57", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 21 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "starIcon", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 22, + "width": 22, + "x": 48, + "y": 2 + }, + "id": "30497D37-61E4-49F9-A617-0BCB56329DE4", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/7dc57eea260f608d09f997083c71f337eda203ca.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "21C0BBC5-9448-4B93-8B15-D9143D9D00E0", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "bellIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 30, + "width": 25.16129032258065, + "x": 16.99999999999998, + "y": 48 + }, + "id": "FD368E38-041A-4075-8FA9-072839FAF85C", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/bb842254e588c527f4071dda96f86e1a2fd87a00.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "30A69901-98CF-41C9-8F46-6C1BDEDD5B31", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "profileIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 34, + "width": 34, + "x": 326, + "y": 48 + }, + "id": "407DEF01-EE38-4546-9C87-1E6A51B66146", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "64AC93AD-B346-42F7-ADEA-702566114106", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Recommended Majors", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Recommended Majors", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 18, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {177, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 179, + "x": 17, + "y": 289 + }, + "id": "BDE3C25F-E16A-443F-886C-674C4334C0E3", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6AAD8DB3-01FC-4157-BA6E-2360E34D220C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Favorites", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Favorites", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 9, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {74, 14}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 75, + "x": 17, + "y": 166 + }, + "id": "A6E38EB0-3205-46BD-A51D-161C9948433C", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "DDDED71F-A840-4CB5-A9AC-719725D8DAF1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "SmallMajorCard", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [ + { + "overrideName": "B7235FC1-37B3-4948-AC8A-02BB2FC6F00B/3DEEC8AC-A192-4E9B-93C7-99F06921F282/E05F3922-7519-44D5-AE71-F903DCFC7581_layerStyle", + "do_objectID": null, + "value": "3EF9F3E0-996F-4084-BDD7-463EFEF0D844" + } + ], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 17, + "y": 199 + }, + "id": "FA945EAE-A00B-43FD-AE9E-B22BFAC7AF59", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E548AB9D-495B-4DAE-A735-7E6DBCDB79E7", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "SmallMajorCard Copy", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [ + { + "overrideName": "B7235FC1-37B3-4948-AC8A-02BB2FC6F00B/3DEEC8AC-A192-4E9B-93C7-99F06921F282/E05F3922-7519-44D5-AE71-F903DCFC7581_layerStyle", + "do_objectID": null, + "value": "3EF9F3E0-996F-4084-BDD7-463EFEF0D844" + } + ], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 195, + "y": 199 + }, + "id": "E3FC77BB-459D-4A8C-B34E-CAFC62C551B6", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4099D0C9-CA8D-4C99-9D3D-8744B181D41F", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "1. Bars / 2. Top Bar / 2. Large / Heading + Search", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 40, + "width": 113, + "x": 15, + "y": 113 + }, + "id": "0488D87A-251E-4DBB-8B34-65E79159236F", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "ABEB9CAF-C965-49E4-85A8-FD5A4482AC86", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "🅰️ Heading", + "nameIsFixed": true, + "resizingConstraint": 41, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": "4475D330-67E5-4F54-AA9A-872C355EA16D", + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.invisionlabs.duplicate": { + "type-duplicate": { + "title": "Advertising", + "action": "article", + "options": { + "section": "advertising", + "type": "title" + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Majors", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 6, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 32 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.3618807196617126, + "green": 0.1713331937789917, + "red": 0.01447581406682729 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "maximumLineHeight": 40, + "minimumLineHeight": 40, + "alignment": 0 + }, + "kerning": 0.6240000000000001 + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{2, 6}, {109, 31}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 40, + "width": 113, + "x": 0, + "y": 0 + }, + "id": "08B25671-7098-4E58-A78D-12A6BBD73714", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "85F610A3-94BD-438B-9495-533E4F18A209", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 32 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.3618807196617126, + "green": 0.1713331937789917, + "red": 0.01447581406682729 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "maximumLineHeight": 40, + "minimumLineHeight": 40, + "alignment": 0 + }, + "kerning": 0.6240000000000001 + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "SmallMajorCard", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 16, + "y": 326 + }, + "id": "AE25D6D2-3E3F-4F4A-ABA3-8F67C2B453E8", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F15B060C-CDFD-4A23-9CF2-06A9616F03C5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "SmallMajorCard Copy 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 16, + "y": 419 + }, + "id": "500B989E-4E28-44D6-A824-8F9E28FE5110", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "15D901F6-0D2E-44B5-93BD-392DAF934390", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "SmallMajorCard Copy 3", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 194, + "y": 419 + }, + "id": "79EA7918-1D80-4D39-A25E-219CB308BE35", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "C59E8323-0CE1-4BBA-B997-65EF6416703B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "SmallMajorCard Copy", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 194, + "y": 326 + }, + "id": "5607F1E5-E776-448E-B553-B145B5365E1F", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B7795373-B7C5-4DFB-AB95-E0B591F9A8B9", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Most Popular Majors", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Most Popular Majors", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 19, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {163, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 164, + "x": 17, + "y": 516 + }, + "id": "B3C9B48B-3DC9-4BB0-9192-C639BC96C97E", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "93AF3420-65D1-4C6B-8A8B-35FD0BB94960", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "SmallMajorCard", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 16, + "y": 549 + }, + "id": "C09DDE33-9148-4463-AF1F-E54492A60D80", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4FC81641-3BEF-4EFF-96DF-7E5E15AFE78D", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "SmallMajorCard Copy 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 17, + "y": 642 + }, + "id": "F48A588A-0CDF-45CC-AED5-47FE9D8FC0C3", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F1A19F6A-BEC1-4F58-B99A-F61A24F1368F", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "SmallMajorCard Copy 3", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 195, + "y": 642 + }, + "id": "3EE91335-877D-40F6-8B3D-819CB678795D", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6E212CD8-7B97-493E-81D8-8096BDEB79CD", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "SmallMajorCard Copy", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 194, + "y": 549 + }, + "id": "670E935D-31C3-4E1A-8562-34655859FAC1", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E57087FE-2F15-4F2C-AC0A-F26408F722FB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Advanced Search", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Advanced Search", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 15, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 14 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.9490196078431372, + "green": 0.5568627450980396, + "red": 0.211764705882353 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 1 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{0, 3}, {114, 11}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 16, + "width": 115, + "x": 245, + "y": 127 + }, + "id": "2F2A173C-F19B-4D5A-978E-3F12106B4137", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "86C3C36E-BE2C-4F24-8B15-BFE3D2A205D6", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 14 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.9490196078431372, + "green": 0.5568627450980396, + "red": 0.211764705882353 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 1 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "normal", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.bohemiancoding.sketchtool.detach": { + "symbolInstance": { + "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 93, + "width": 375, + "x": 0, + "y": 724 + } + }, + "symbolMaster": { + "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", + "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" + } + }, + "com.sketch.detach": { + "symbolInstance": { + "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 93, + "width": 375, + "x": 0, + "y": 724 + } + }, + "symbolMaster": { + "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", + "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 56, + "width": 302, + "x": 40, + "y": 734 + }, + "id": "68CA9079-975B-41F8-918A-81F81C663A89", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F71BC2DA-F20D-49FC-8AA1-76DD21DFB8A9", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "homeicon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 24.2734375, + "width": 26, + "x": 0, + "y": 16.86328125 + }, + "id": "81B176D5-B951-400A-A3F9-C23398FD71FA", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/724477925ebd536321fbadee7e227cfd057eb0f5.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "D856B0FA-B9DE-497B-A296-07C6A94FAADC", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7294117647058823, + "green": 0.6235294117647059, + "red": 0.5843137254901961 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "BBD21E46-AD9D-4372-AE85-42558046DA42", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "stats", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "BBD21E46-AD9D-4372-AE85-42558046DA42", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 24, + "width": 24, + "x": 208, + "y": 19 + }, + "id": "97759941-CDEC-4124-BD75-CF252BDF31A9", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/791dd23b4cf727cd2ad676896de2196a29d57e2d.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "682EFF94-01D4-4882-9F1D-36459ECB1718", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "plus-icon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 56, + "width": 50.90909090909091, + "x": 122.0000000000001, + "y": 0 + }, + "id": "D2A3113D-06F0-4E2D-BAFF-828FE420A825", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/c4eea6263c1c1732dcb7a96694a80dd390a1ff7d.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "78AB3AC4-4205-4A7C-B713-9413D90C1963", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "not published", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 23.33333333333333, + "width": 23.33333333333333, + "x": 69, + "y": 18 + }, + "id": "CF548824-145B-4B9B-91FF-2780A4350CC0", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5c0161e4cd699ec44a35f72b3b4b529f464c6f94.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "3119424D-99FC-4F53-82F8-B778935443EA", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "learn", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 21, + "width": 24, + "x": 278, + "y": 23 + }, + "id": "7192C076-B6DB-40AA-92C5-AC2CE1217A9F", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5ce1816426a25e74eb636fbaa1e06a6627b7d7ee.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "7648BBE9-332A-41E8-BBEA-C55FDA73F9FF", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "CLASS_NAME": null, + "type": "artboard", + "includeInCloudUpload": true, + "includeBackgroundColorInExport": true, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "layout": null, + "grid": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 812, + "width": 375, + "x": 690, + "y": -295 + }, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "id": "22155B2E-9044-4DCD-A0D1-C5656655323A", + "hasBackgroundColor": true, + "isFlowHome": false, + "resizesContent": false, + "presetDictionary": { + "height": 812, + "offersLandscapeVariant": 1, + "name": "iPhone X", + "width": 375, + "allowResizedMatching": 1 + }, + "visible": true, + "style": { + "_class": "style", + "do_objectID": "274DBB7E-AB41-4ED0-991E-481F1A1008BD", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "artboard" + }, + "azure_blob_uri": "/A1CA9316-82B5-4270-B143-97575F0EC1D0.png" + }, + { + "pbdfType": "screen", + "id": "7abb7146-7156-4fa4-8e2d-f816fd51ed27", + "name": "icons/tabbar/home", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "jpg", + "name": "", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Landing Page", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + }, + "io.magicsketch.mirror": { + "highestQuality": -1 + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "iPhone X Blue@3x", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 216, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 413, + "width": 221, + "x": 78, + "y": 106 + }, + "id": "91EDA7BB-F048-429A-A4AB-0920FF86EE3F", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/d9ac02d78c4b82b0cacb3dc59abb1eaab6827753.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "45D00E60-3AFA-4221-8AC0-965CE88C0846", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 0, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 271, + "width": 375, + "x": 0, + "y": 541 + }, + "id": "9F5E1EE0-3953-4C24-9E5E-036025B119D6", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4F65EB72-BD53-4B00-8808-A8166D6B5FCA", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "A new way to learn a", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "A new way to learn about careers", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 32, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 16 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.3618807196617126, + "green": 0.1713331937789917, + "red": 0.01447581406682729 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + }, + "kerning": 0.2222222222222222 + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{9, 3}, {273, 16}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 19, + "width": 292, + "x": 41, + "y": 563 + }, + "id": "11EF6BCF-F96E-4BBA-9A76-DEAF21E67591", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "DF0B020C-E294-4478-B0BD-A53451DC2414", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 16 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.3618807196617126, + "green": 0.1713331937789917, + "red": 0.01447581406682729 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + }, + "kerning": 0.2222222222222222 + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Inspyred provides re", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Inspyred provides resources to help you make the best decisions.", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 64, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Medium", + "size": 13 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.6196078431372549, + "green": 0.5254901960784314, + "red": 0.4666666666666667 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "maximumLineHeight": 20, + "minimumLineHeight": 20, + "alignment": 2 + }, + "kerning": 0.111 + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{4, 5}, {228, 33}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 40, + "width": 235, + "x": 70, + "y": 592 + }, + "id": "1BA3BFB1-0BBC-426F-BDFD-52F4F96A051B", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "285058DB-F572-4EA0-9A96-E6AB58EF6A87", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Medium", + "size": 13 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.6196078431372549, + "green": 0.5254901960784314, + "red": 0.4666666666666667 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "maximumLineHeight": 20, + "minimumLineHeight": 20, + "alignment": 2 + }, + "kerning": 0.111 + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Main-button", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 42, + "width": 288, + "x": 44, + "y": 664 + }, + "id": "4E64D8E6-3CA3-4FD8-B4A2-00F37A01D3DD", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "46BA520C-4552-476C-B9D6-DAC71E3100FD", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Create Account", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 42, + "width": 288, + "x": 0, + "y": 0 + }, + "id": "9CDBDB86-8D3E-4195-85C8-6C277B887D2F", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "A4DBF255-AC62-4732-ABFE-3F107AAF944A", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": "352ED728-3274-4B9B-A8E1-519933787FAD", + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 100, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 100, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 100, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 100, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 100, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 42, + "width": 288, + "x": 0, + "y": 0 + }, + "id": "6A00ABC1-630E-4D11-9E85-B6AFF6327E7D", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "2760AE32-E436-4CE7-BE88-6F7128034496", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.2078431372549019 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Sign Up", + "nameIsFixed": true, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": "447EE00B-5E7B-44E6-A556-1E2D6B154DF8", + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Sign Up", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 7, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Medium", + "size": 16 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + }, + "MSAttributedStringTextTransformAttribute": 1 + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{1, 3}, {65, 13}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 19, + "width": 66, + "x": 111, + "y": 12 + }, + "id": "6C3213BD-D9C0-4385-8070-D237D233D1DA", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "29B129BE-4C28-4107-AAF1-F93CD824C91B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Medium", + "size": 16 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "MSAttributedStringTextTransformAttribute": 1, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Create Account", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 42, + "width": 288, + "x": 44, + "y": 725 + }, + "id": "4928E2BE-EDE9-404C-8995-B7C470D3B523", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "DBB029E0-E7A9-4CBA-9049-E791D44B7B1F", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": "352ED728-3274-4B9B-A8E1-519933787FAD", + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 100, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 100, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 100, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 100, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 100, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 42, + "width": 288, + "x": 0, + "y": 0 + }, + "id": "F478F1A9-7453-4631-85DD-85F38C4AC994", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "0F6F633A-E26B-4423-A195-23505F8930A7", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 0, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Log in", + "nameIsFixed": true, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": "447EE00B-5E7B-44E6-A556-1E2D6B154DF8", + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Log in", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 6, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Medium", + "size": 16 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.4921875, + "green": 0.4921875, + "red": 0.4921875 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + }, + "MSAttributedStringTextTransformAttribute": 1 + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{1, 3}, {53, 13}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 19, + "width": 55, + "x": 116.5, + "y": 12 + }, + "id": "3E3BE211-8D70-4F7C-8FA2-1929F6008911", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "01CDCF6A-40F6-4E2D-9F80-3A765CED87ED", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Medium", + "size": 16 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.4921875, + "green": 0.4921875, + "red": 0.4921875 + }, + "MSAttributedStringTextTransformAttribute": 1, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "header", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 375, + "x": 0, + "y": 0 + }, + "id": "63251011-40E5-4A48-873F-1B5B7F32B840", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "63A6B68C-880C-4CC6-8138-77FE3802D23A", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 0, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 375, + "x": 0, + "y": 0 + }, + "id": "99548B48-5932-4ED7-8688-3D5861018474", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "BCBC34A6-9894-4912-B1DD-47591462EB25", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.207843137254902 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + }, + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.2078431372549019 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "userScore", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 25, + "width": 70, + "x": 153, + "y": 51 + }, + "id": "9C99686A-6AF1-4DC2-A5A6-D418EF354490", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "A304CF40-9A91-4A7A-96C0-48ABD4BD7956", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "285", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "285", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 3, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 21 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{1, 5}, {38, 16}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 25, + "width": 40, + "x": 0, + "y": 0 + }, + "id": "29326099-B5C1-4B12-9A66-B98D0D75C21C", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F83E766B-7657-429A-AF76-A4126C261CDE", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 21 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "starIcon", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 22, + "width": 22, + "x": 48, + "y": 2 + }, + "id": "B2761F8E-7B41-4833-A0E8-7F6082DD5C12", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/7dc57eea260f608d09f997083c71f337eda203ca.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F7742F48-B8F2-4433-8A53-01EAAE777032", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "bellIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 30, + "width": 25, + "x": 17, + "y": 48 + }, + "id": "FF62F74F-C6A7-4EB0-ACC5-8E3682B5D5F9", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/bb842254e588c527f4071dda96f86e1a2fd87a00.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "44C3DDF1-0F00-4EB7-ABD8-F8BDE9E8C217", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "profileIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 34, + "width": 34, + "x": 326, + "y": 48 + }, + "id": "C0F28883-43D1-47F0-8FE4-68E054EE17D6", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "1F25C912-EA13-4DD4-88C3-91C6984220C1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "CLASS_NAME": null, + "type": "artboard", + "includeInCloudUpload": true, + "includeBackgroundColorInExport": true, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "layout": null, + "grid": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 812, + "width": 375, + "x": 2154, + "y": -295 + }, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "id": "36EB4CE8-41DD-4EDE-A4BD-ED88D043D9F1", + "hasBackgroundColor": true, + "isFlowHome": true, + "resizesContent": false, + "presetDictionary": { + "width": 375, + "offersLandscapeVariant": 1, + "height": 812, + "allowResizedMatching": 1, + "name": "iPhone X" + }, + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E72ACE4B-4154-4BAC-BBD0-FC04480E49F5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "artboard" + }, + "azure_blob_uri": "/7ABB7146-7156-4FA4-8E2D-F816FD51ED27.png" + }, + { + "pbdfType": "screen", + "id": "53d04c05-9e5d-4f7a-8765-7dbea892d0b5", + "name": "person/6", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "jpg", + "name": "", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Community Groups", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + }, + "io.magicsketch.mirror": { + "highestQuality": -1 + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "header", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.bohemiancoding.sketchtool.detach": { + "symbolInstance": { + "do_objectID": "C7D593F6-8A76-4439-9684-505554F82229", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 375, + "x": 0, + "y": 0 + } + }, + "symbolMaster": { + "do_objectID": "ADF19C17-3F52-4FE3-B207-2A6E6AC2DB95", + "symbolID": "65B0D541-BC41-4E38-81E3-41E0946BC70B" + } + }, + "com.sketch.detach": { + "symbolInstance": { + "do_objectID": "C7D593F6-8A76-4439-9684-505554F82229", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 375, + "x": 0, + "y": 0 + } + }, + "symbolMaster": { + "do_objectID": "ADF19C17-3F52-4FE3-B207-2A6E6AC2DB95", + "symbolID": "65B0D541-BC41-4E38-81E3-41E0946BC70B" + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 375, + "x": 0, + "y": 0 + }, + "id": "3A37FC24-9DA4-4A94-AB11-5183101C9BB2", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "BD13C2FD-BDF7-4499-8BCC-98200B921102", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 0, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 375, + "x": 0, + "y": 0 + }, + "id": "E879766B-336D-448D-A583-DAFCD0349D06", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "7781FF84-5E04-445D-B269-2B4E52473CB3", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.2078431372549019 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.207843137254902 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "userScore", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 25, + "width": 70, + "x": 153, + "y": 51 + }, + "id": "F98C8691-2415-4182-A967-9C044B8A7EFE", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "9788D9D7-A7D5-413D-BC43-A87A113981BF", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "285", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "285", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 3, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 21 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 5}, {38, 16}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 25, + "width": 40, + "x": 0, + "y": 0 + }, + "id": "F23BD062-473C-4CA4-A6B5-22178319C9E2", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "D642968B-DD1F-4EB7-ABF0-7E3A2596EF6A", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 21 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "starIcon", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 22, + "width": 22, + "x": 48, + "y": 2 + }, + "id": "16416ED0-5F5A-4910-B0AD-60E53BCAA1A0", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/7dc57eea260f608d09f997083c71f337eda203ca.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "06DE097D-7125-4375-BDB7-A32DDBA2A887", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "bellIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 29.2258064516129, + "width": 25.16129032258065, + "x": 16.99999999999998, + "y": 48.77419354838709 + }, + "id": "63F24305-CB55-4B5B-A073-D38836E0927F", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/1ab87eea21615010a2576c5a46416a88641231ec.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "2350971C-AD03-4398-B906-228AD1248B5A", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "profileIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 34, + "width": 34, + "x": 326, + "y": 48 + }, + "id": "91B172C3-266A-4631-85A9-53357F95CAE3", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "1CC75F68-D52B-4597-B22A-03E9C13C5D6D", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Your Groups", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Your Groups", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 11, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{0, 4}, {97, 15}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 98, + "x": 17, + "y": 111 + }, + "id": "67022F73-66AB-4888-99EE-0A014880FFE5", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "2D7E06F9-FA19-4C76-BED0-8813A7741194", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "More Groups", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "More Groups", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 11, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 4}, {101, 15}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 102, + "x": 17, + "y": 299 + }, + "id": "8781D32E-2E85-4C2A-8FB7-AC969364CA09", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "2024D5D8-A0E6-4149-B95A-14FD08AE9268", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Cell1", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 124, + "width": 245, + "x": 17, + "y": 148 + }, + "id": "B79FE1C9-5B34-437B-9132-2581EB447D55", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "34F63DEA-F7C2-4809-9F16-6D2DD2E8CDC7", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 10, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 124, + "width": 245, + "x": 0, + "y": 0 + }, + "id": "6D3D3561-4E59-493E-85F4-272607A395AA", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "00126421-C6AE-446A-B98D-F77373FD8005", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "High School Group", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "High School Group", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 17, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {144, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 146, + "x": 14, + "y": 13 + }, + "id": "40C6CFBC-7962-497A-8D3D-3F4C43B0D5F1", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "651B9724-330B-4765-BC5B-27B749FE582F", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "People Group 1", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 89, + "x": 14, + "y": 68 + }, + "id": "01E8E835-9FED-487B-BB8C-E6895C19436F", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "3FE98165-00DA-4823-BB6C-C4536B928DA1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person 9", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [ + { + "overrideName": "D6CDCF6E-5E0B-4FD4-9EEC-11BEF7583021_symbolID", + "do_objectID": null, + "value": "" + } + ], + "scale": 1, + "symbolID": "00121EBB-86F2-4C74-8A1D-074B52B33010", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "CDAB5F56-F495-4512-BD9A-1DA67226ACBA", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "BCEA4D9D-4DE6-4CDA-AAF8-58943055C622", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person 9", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [ + { + "overrideName": "A268549D-9BCF-41CE-B386-6FFC1C85817B_symbolID", + "do_objectID": null, + "value": "530E093C-4A76-41F1-9482-08004D962CD5" + } + ], + "scale": 1, + "symbolID": "1E69FEC0-85F8-42BA-A987-F973EC2F19A8", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 24, + "y": 0 + }, + "id": "99F3048C-B378-4CBC-B6BB-F65F7922FD28", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "39C1D372-28A0-4AEB-A8DE-F1ABB723EE31", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person 9 copy", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [ + { + "overrideName": "A268549D-9BCF-41CE-B386-6FFC1C85817B_symbolID", + "do_objectID": null, + "value": "292AFD52-31A6-40B2-B087-3C35E9191616" + } + ], + "scale": 1, + "symbolID": "1E69FEC0-85F8-42BA-A987-F973EC2F19A8", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 48, + "y": 0 + }, + "id": "7C0FBBA7-8159-4646-B9E6-ACF888E27AEA", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F46EC120-54CD-4423-AFC2-639A1A0F629F", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Cell2", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 124, + "width": 245, + "x": 274, + "y": 148 + }, + "id": "F4F240C2-8169-48F4-9847-E2EA100E466D", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "EB9984DF-D61C-45A4-B61A-59C12C86B082", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 10, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 124, + "width": 245, + "x": 0, + "y": 0 + }, + "id": "8DFBAE27-3655-4D04-9801-20DBDE6BC2B0", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "03BF79D3-C3F9-484A-94D5-3BC57B4AD5CA", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Programming", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Programming", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 11, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {105, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 107, + "x": 26, + "y": 13 + }, + "id": "B9BE2B17-BEA2-44CB-95C8-9E30A067CFBF", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "78D56614-CF62-4103-8266-8C219A61C686", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "People Group 2", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 89, + "x": 26, + "y": 68 + }, + "id": "37511FBB-B56B-4147-8A66-0AC2D10F8B53", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "A03D03E3-AFE9-48F6-9DFE-6DA124466447", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person 9 copy 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "7ABF1A2D-5708-4024-81DA-F0C183CB18AA", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "068DAB0A-9AB7-4DAA-B9F4-2068B9C655B3", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person/5", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "29155DF5-855F-4948-9C6C-935F9F9DD81E", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "4C59C535-CE42-4D64-A52A-E67B51A66AB6", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F34DEB8E-9955-4560-89E2-40B2E80E24BC", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person/frame", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "9912193F-5440-41AC-BB51-C6001980B1CE", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "5E9D1FA5-635F-421B-A6E5-FD4DC43541EC", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person 9 copy 3", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 24, + "y": 0 + }, + "id": "340FDA42-D564-4545-94C2-1158AE4B6F7C", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F6A4FBEA-7939-4641-A4E6-51944A3E7D45", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person/5", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "97736C0F-6E1F-4671-912F-003C97ACDE40", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "9CB2FBCF-7014-4C54-9768-D7C5343D1A8A", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "FC663A2E-AD33-404F-B315-BCDDB7AF3DB9", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person/frame", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "44826B0C-228E-4CDB-88DD-EAE3F11211C1", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "C8D7E19F-6D3B-4FE1-AD33-527CE0DCB142", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person 9 copy 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 48, + "y": 0 + }, + "id": "5629672A-EB36-4712-AEA9-17D262153C00", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4FB1487E-AFF3-4937-AEEF-A5AB207B34FC", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person/5", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "477112E3-2915-42AA-96E2-BFD71521C33D", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "4008399E-04C4-4C36-83D8-3E101BCB21F9", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4AFF161F-45D7-487E-B847-E2807F941DDF", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person/frame", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "C289F2E4-82A8-4453-A2C6-E80A5562602B", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "2D33DC74-0136-41FB-A9FC-8B2916CA1F5C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "groups", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 344, + "width": 358, + "x": 17, + "y": 372 + }, + "id": "693EA2A3-1F1D-4913-B010-059737882017", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "0C0AD29A-0597-44EB-8D8A-BCF993CE1F57", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Algorithms", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Algorithms", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 10, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{0, 3}, {86, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 87, + "x": 0, + "y": 0 + }, + "id": "8CDC477E-FF4F-42DC-9259-C621C3F52632", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6710AA96-32A4-4D98-92DF-99B2BD3BC559", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Nursing", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Nursing", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 7, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {60, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 62, + "x": 0, + "y": 65 + }, + "id": "AE9DFE1E-3AE8-4546-81A6-CAB26D5772B2", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "76C0FACE-B6A4-4077-A1C3-7C34456821C0", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Dog Photos", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Dog Photos", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 10, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 4}, {88, 16}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 90, + "x": 0, + "y": 130 + }, + "id": "A9619FE1-6724-489E-88AD-03649DD72DCA", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "88A7AB46-FDEE-4D0B-B2F5-0448475EA3CD", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Sports", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Sports", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 6, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{0, 4}, {51, 15}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 52, + "x": 0, + "y": 195 + }, + "id": "AB5B3E70-12AA-42AD-924A-25F385BABFBE", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "BBBA777C-4F22-4787-B73D-244FDDF6E4FA", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Band", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Band", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 4, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 4}, {38, 13}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 41, + "x": 0, + "y": 259 + }, + "id": "0BE64048-7FCC-472D-9DB0-9382BA761844", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "7F783BF9-2DE4-436F-9B76-DEFE802A7DA1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Party time", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Party time", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 10, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {80, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 82, + "x": 0, + "y": 324 + }, + "id": "B7486DA7-30A6-4078-98A3-569D5C181043", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F16ED156-1A04-4A49-928C-34F73105EAE5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Line Copy", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": false, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0.49999999999999994}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 2, + "width": 354, + "x": 4, + "y": 40 + }, + "id": "C3124E8F-BFCC-4BAF-905E-D65A3770CD26", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "5BD035B8-4865-49FD-9433-7F344141E333", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 0, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": false, + "dashPattern": [], + "lineCapStyle": 2, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7843137254901961, + "green": 0.7568627450980392, + "red": 0.7372549019607844 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Line Copy 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": false, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0.49999999999999994}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 2, + "width": 354, + "x": 4, + "y": 105 + }, + "id": "15D6BF49-8EF7-4725-9CC0-696BEF2B2105", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "22FE69B4-FFF9-4DCE-914B-A5C8914EE9FB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 0, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": false, + "dashPattern": [], + "lineCapStyle": 2, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7843137254901961, + "green": 0.7568627450980392, + "red": 0.7372549019607844 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Line Copy 3", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": false, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0.49999999999999994}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 2, + "width": 354, + "x": 4, + "y": 170 + }, + "id": "DAF36D0C-277E-449E-BF19-E245BDC03E8C", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "946D5869-99AC-4129-BD81-94ABA295B2A6", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 0, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": false, + "dashPattern": [], + "lineCapStyle": 2, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7843137254901961, + "green": 0.7568627450980392, + "red": 0.7372549019607844 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Line Copy 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": false, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0.49999999999999994}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 2, + "width": 354, + "x": 4, + "y": 235 + }, + "id": "CB2AD56A-78E0-4456-BA5B-CDFA26756CC0", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "2314069D-98E1-4FCE-A1FE-F3E0B245E0A9", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 0, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": false, + "dashPattern": [], + "lineCapStyle": 2, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7843137254901961, + "green": 0.7568627450980392, + "red": 0.7372549019607844 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Line Copy 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": false, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0.49999999999999994}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.49999999999999994}", + "curveMode": 1, + "curveTo": "{0, 0.49999999999999994}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 2, + "width": 354, + "x": 4, + "y": 299 + }, + "id": "C8876F24-8460-4D10-8987-A886C2258E14", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "202AD07B-86D8-4318-95E8-ECB67EC2F10A", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 0, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": false, + "dashPattern": [], + "lineCapStyle": 2, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7843137254901961, + "green": 0.7568627450980392, + "red": 0.7372549019607844 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Line", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": false, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.112, 0.49999999999999933}", + "curveMode": 1, + "curveTo": "{0.112, 0.49999999999999933}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.112, 0.49999999999999933}", + "curveMode": 1, + "curveTo": "{0.112, 0.49999999999999933}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 1, + "width": 187.5, + "x": 0, + "y": 337 + }, + "id": "E7FC09F6-0B0F-409D-9D25-5C6187009ABB", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E1FEC734-9C06-4233-94FA-577811F35BB3", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 0, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": false, + "dashPattern": [], + "lineCapStyle": 2, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 0.5176470588235293, + "red": 0 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 3 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "normal", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.bohemiancoding.sketchtool.detach": { + "symbolInstance": { + "do_objectID": "C441BE9F-7AE4-4D86-8C5E-1FE28B1B146F", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 93, + "width": 375, + "x": 0, + "y": 719 + } + }, + "symbolMaster": { + "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", + "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" + } + }, + "com.sketch.detach": { + "symbolInstance": { + "do_objectID": "C441BE9F-7AE4-4D86-8C5E-1FE28B1B146F", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 93, + "width": 375, + "x": 0, + "y": 719 + } + }, + "symbolMaster": { + "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", + "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 56, + "width": 302, + "x": 40, + "y": 729 + }, + "id": "E5EBC598-D3D9-4F0B-A8AF-93C9283840B6", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "41E1E1AE-B64F-4DC0-B27E-9C52D99E7875", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "homeicon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 24.2734375, + "width": 26, + "x": 0, + "y": 16.86328125 + }, + "id": "59F5955C-E074-4E0C-958E-A4877439B42A", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/724477925ebd536321fbadee7e227cfd057eb0f5.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "63D4D0F5-909A-4C9A-8846-96D6CEEDD57A", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7294117647058823, + "green": 0.6235294117647059, + "red": 0.5843137254901961 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "stats", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 24, + "width": 24, + "x": 208, + "y": 19 + }, + "id": "36E1159D-0BCC-4608-AEDF-668E08643457", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/791dd23b4cf727cd2ad676896de2196a29d57e2d.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "1A0788EB-E8B4-4442-8217-A2617525798B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "plus-icon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 56, + "width": 50.90909090909091, + "x": 122, + "y": 0 + }, + "id": "38142621-3AFF-4B56-B147-ECB7916D5CBF", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/c4eea6263c1c1732dcb7a96694a80dd390a1ff7d.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "30ACA845-DE4C-4776-A013-F5F4FB062ADE", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "22155B2E-9044-4DCD-A0D1-C5656655323A", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "not published", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "22155B2E-9044-4DCD-A0D1-C5656655323A", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 23.33333333333333, + "width": 23.33333333333333, + "x": 69, + "y": 18 + }, + "id": "A5FF612E-E3F3-4705-B566-022050D92A93", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5c0161e4cd699ec44a35f72b3b4b529f464c6f94.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "8D87A4E1-4AF3-416C-A4A9-593839693D6C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "learn", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 21, + "width": 24, + "x": 278, + "y": 23 + }, + "id": "AB138350-BAC4-4E1D-9E46-43C0105EDED5", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5ce1816426a25e74eb636fbaa1e06a6627b7d7ee.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "634B2EC5-3A62-4B27-809F-7C0BAF5CB06E", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Create New", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Create New", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 10, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 14 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.8862745098039215, + "green": 0.4823529411764704, + "red": 0.207843137254902 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "allowsDefaultTighteningForTruncation": 0, + "alignment": 0 + }, + "kerning": -0.224 + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{0, 3}, {72, 11}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 16, + "width": 72, + "x": 267, + "y": 114 + }, + "id": "BE18F369-3584-46BB-9F9F-E60EDC6BC64E", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "93574C40-E84A-482F-904D-EB8849A05625", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 14 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.8862745098039215, + "green": 0.4823529411764704, + "red": 0.207843137254902 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "allowsDefaultTighteningForTruncation": 0, + "alignment": 0 + }, + "kerning": -0.224 + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + } + ], + "CLASS_NAME": null, + "type": "artboard", + "includeInCloudUpload": true, + "includeBackgroundColorInExport": true, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "layout": null, + "grid": { + "_class": "simpleGrid", + "isEnabled": false, + "gridSize": 20, + "thickGridTimes": 10 + }, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 812, + "width": 375, + "x": 1679, + "y": -295 + }, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "id": "BBD21E46-AD9D-4372-AE85-42558046DA42", + "hasBackgroundColor": true, + "isFlowHome": false, + "resizesContent": false, + "presetDictionary": { + "allowResizedMatching": 1, + "offersLandscapeVariant": 1, + "name": "iPhone X", + "height": 812, + "width": 375 + }, + "visible": true, + "style": { + "_class": "style", + "do_objectID": "2CCDC855-B2FE-43FF-9023-384A0E8C46FA", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "artboard" + }, + "azure_blob_uri": "/53D04C05-9E5D-4F7A-8765-7DBEA892D0B5.png" + }, + { + "pbdfType": "screen", + "id": "b8f978e3-16b6-4278-b836-b67e3f123c68", + "name": "person/8", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "HomeScreenAlt", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "someElement/default", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "3156C515-06F6-428E-8A5B-CB8B85B1F7F4", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 560, + "width": 419, + "x": -5, + "y": 0 + }, + "id": "4E81F228-20E6-45BA-9864-1B6830B51F5E", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "9E2D66E8-3133-4F0D-95A3-090C3847C4E1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Top Stack Section", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 560, + "width": 414, + "x": 0, + "y": 50 + }, + "id": "64B9FF31-0809-4857-9A5E-E3F1E82A47BB", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6A4DFD07-4C2D-4232-BB6E-DB57556781D6", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Group 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 44, + "width": 258, + "x": 79, + "y": 81 + }, + "id": "DA7A85FF-BEC3-422D-B4C7-A0D6EAADF6E2", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E1BDF8D4-0E9B-4410-BB8B-7925F41F0A9A", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Noam Levine", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Noam Levine", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 11, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{6, 3}, {104, 14}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 115.7692307692308, + "x": 70.56410256410257, + "y": 0.4761904761904763 + }, + "id": "E4C1DD25-DED6-4DA3-98F5-94AE78F86827", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "5D394956-B0F8-4A48-B3AA-E8C276D8CD7C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Student at Hanks Hig", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Student at Hanks High School", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 28, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{13, 3}, {231, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 256.8974358974359, + "x": 0.5512820512820513, + "y": 23.52380952380953 + }, + "id": "0018EBA8-F3B8-4971-ADED-C455BCC732A3", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "3EEE6295-D658-4DAB-965F-B74CCAA48109", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Completion Graph", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 88, + "width": 131, + "x": 142, + "y": 235 + }, + "id": "D78502A3-1F0A-449D-9671-08651CA5C85F", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "2789C32A-D50A-46C6-BE25-12D4AC0D8B96", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 8.185654008438819, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "72%", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "72%", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 3, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 60.30155896069287 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{2, 15}, {115, 43}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 72, + "width": 131, + "x": 0, + "y": 0.117647058823529 + }, + "id": "B74C9066-66DE-4A79-A313-3F4CB8C486C8", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "96914655-3032-4836-9D2B-D7C642809CB7", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 8.375216522318453, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.9411764705882353, + "green": 0.4549019607843137, + "red": 0.2784313725490197 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.207843137254902 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 60.30155896069287 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Completed", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Completed", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 9, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 15.91291139240506 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 0.8, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{0, 3}, {81, 15}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 19, + "width": 91.36974789915965, + "x": 19.81512605042008, + "y": 68.44117647058823 + }, + "id": "A3D16E96-F0BA-4297-8FB6-E876A73200C7", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6F5203AE-C12D-481E-BDEA-DF553E8BBBEB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 8.375216522318453, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.9411764705882353, + "green": 0.4549019607843137, + "red": 0.2784313725490197 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.207843137254902 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 15.91291139240506 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 0.8, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "ScoreCard", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 128, + "width": 414, + "x": 0, + "y": 432 + }, + "id": "0002CDDE-C2AB-4063-8621-F9C29431D10A", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "DA4357B2-124E-48B9-81AB-340419E1BF11", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Score Bar@3x", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 216, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 128, + "width": 414, + "x": 0, + "y": 0 + }, + "id": "FC2F0364-7AC3-4544-88B1-4B5325E6BFF7", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/896d0b8336868d41380f511f76aaff0ff80b0986.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "786CF742-FD2C-4885-9698-B6ED4F3A2056", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Score: 285", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Score: 285", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 7, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 22 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.1996332757179576, + "green": 0.1996332757179576, + "red": 0.2154815051020408 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + }, + { + "_class": "stringAttribute", + "location": 7, + "length": 3, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 22 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.9333333333333333, + "green": 0.5372549019607842, + "red": 0.2078431372549019 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 3, + "textBehaviour": 1, + "glyphBounds": "{{6, 6}, {113, 16}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 26, + "width": 125.856, + "x": 144.072, + "y": 40.9504132231405 + }, + "id": "23B2A6D4-19C3-4998-835E-EE0EA730987A", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "156269BE-EF3F-47EC-A992-131FEAC1ABFB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 22 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.1996332757179576, + "green": 0.1996332757179576, + "red": 0.2154815051020408 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "profileIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 36, + "width": 38, + "x": 357, + "y": 0 + }, + "id": "4B59724C-6636-4A01-9194-ED2FA00779C1", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "ACFBAC63-A7D3-4E33-9BEF-9CD31D9621DC", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "bellIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 30, + "width": 28, + "x": 19, + "y": 3 + }, + "id": "289A647A-AC32-4A2E-B728-4834755FB106", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/1ab87eea21615010a2576c5a46416a88641231ec.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "02C7F5B6-61E8-4FA8-B219-F3040760A11B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Connect Facebook Button", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 342, + "x": 36, + "y": 610 + }, + "id": "A303AE9A-A3FD-48E7-9EB7-3D43C33D87DB", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F60AECE7-6562-4E32-AB5C-A7FC92986CCF", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 342, + "x": 0, + "y": 0 + }, + "id": "897E1F6A-D392-461A-A78A-648C89309CE9", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B0B03806-1FAD-4B94-921A-401C3F148C73", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Rectangle 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": true, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 30.5, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 30.5, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 30.5, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 30.5, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 100, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 342, + "x": 0, + "y": 0 + }, + "id": "AE753A74-1CAE-4B27-BCD7-0D38E72A9A4D", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B11425D9-E295-4191-9B89-B7E2722D0CF3", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + }, + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 0.6980392156862745, + "green": 0.4039215686274508, + "red": 0.2588235294117647 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Continue", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Connect facebook", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 16, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "paragraphSpacing": 2.299999952316284, + "alignment": 0 + }, + "MSAttributedStringTextTransformAttribute": 1 + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{0, 3}, {186, 14}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 186, + "x": 88, + "y": 21 + }, + "id": "7B262F2E-F2B8-4F32-BF45-ABD68C860FA6", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B486C1BB-1066-40E1-BF5C-9200A16788F3", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0, 0}", + "gradientType": 0, + "to": "{1, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.9137254901960784, + "green": 0.3529411764705881, + "red": 0.3568627450980389 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.9411764705882353, + "green": 0.4549019607843137, + "red": 0.2784313725490197 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "MSAttributedStringTextTransformAttribute": 1, + "paragraphStyle": { + "_class": "paragraphStyle", + "paragraphSpacing": 2.299999952316284, + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Page 1", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 61, + "x": 0, + "y": 0 + }, + "id": "252A7A3A-BD0B-4C7A-8156-06960F1624CA", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "CE757C0D-F861-4DF0-A811-9EC87BCF80A2", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 12.70833333333333, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Oval 5", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "constraints": { + "scaleFactor": 1, + "model_version": 0.1, + "aspectRatio": { + "model_version": 0.1, + "enabled": 1, + "multiplier": 60.93646, + "modelID": "constraint_a76df48e-bf62-4625-934e-d88b37589797", + "model_class": "ADModelConstraint", + "constant": 60.93646 + }, + "modelID": "viewConstraints_83e4874d-5168-4c05-9eb7-e242e4e7297a", + "model_class": "ADModelViewConstraints", + "automatic": 1 + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614237490000004, 1}", + "curveMode": 2, + "curveTo": "{0.22385762510000001, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385762510000001}", + "curveMode": 2, + "curveTo": "{1, 0.77614237490000004}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22385762510000001, 0}", + "curveMode": 2, + "curveTo": "{0.77614237490000004, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77614237490000004}", + "curveMode": 2, + "curveTo": "{0, 0.22385762510000001}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 61, + "width": 61, + "x": 0, + "y": 0 + }, + "id": "E2661B1C-876F-468C-A528-FC7A1ABBDE51", + "type": "oval", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "542D78E0-DAD6-4100-B2D3-EEA197358AB7", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 12.70833333333333, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 1.270833333333333 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.6980392156862745, + "green": 0.4039215686274508, + "red": 0.2588235294117647 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "oval" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Fill 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.94393217672507967, 0.55011276448004953}", + "curveMode": 1, + "curveTo": "{0.94393217672507967, 0.55011276448004953}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.94393217672507967, 0.55011276448004953}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.98806974609972453, 0.37028641604067547}", + "curveMode": 1, + "curveTo": "{0.98806974609972453, 0.37028641604067547}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.98806974609972453, 0.37028641604067547}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.64910632347157293, 0.37028641604067547}", + "curveMode": 1, + "curveTo": "{0.64910632347157293, 0.37028641604067547}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.64910632347157293, 0.37028641604067547}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.64910632347157293, 0.20342367881921516}", + "curveMode": 4, + "curveTo": "{0.64910632347157293, 0.25548471510470155}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.64910632347157293, 0.25548471510470155}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.81871913647686034, 0.16795308079445873}", + "curveMode": 4, + "curveTo": "{0.67659397806231703, 0.16795308079445873}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.81871913647686034, 0.16795308079445873}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.16791291024176927}", + "curveMode": 1, + "curveTo": "{1, 0.16791291024176927}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0.16791291024176927}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.96864484551850716, 0.0049008074281089711}", + "curveMode": 4, + "curveTo": "{1, 0.0070872332244901791}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{1, 0.0070872332244901791}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.47452257134117021, 0}", + "curveMode": 3, + "curveTo": "{0.86104313245640873, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.7358300922081894, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.29559061311890933, 0.23768916026328918}", + "curveMode": 4, + "curveTo": "{0.29559061311890933, 0.083801511560511244}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.29559061311890933, 0.23768916026328918}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.29559061311890933, 0.37028641604067547}", + "curveMode": 1, + "curveTo": "{0.29559061311890933, 0.37028641604067547}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.29559061311890933, 0.37028641604067547}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.37028641604067547}", + "curveMode": 1, + "curveTo": "{0, 0.37028641604067547}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0.37028641604067547}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.55011276448004953}", + "curveMode": 1, + "curveTo": "{0, 0.55011276448004953}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0.55011276448004953}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.29559061311890933, 0.55011276448004953}", + "curveMode": 1, + "curveTo": "{0.29559061311890933, 0.55011276448004953}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.29559061311890933, 0.55011276448004953}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.41857492461652751, 0.99944908956311651}", + "curveMode": 4, + "curveTo": "{0.29559061311890933, 1}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.29559061311890933, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.64910632347157293, 0.97130674807898676}", + "curveMode": 4, + "curveTo": "{0.53727658086789309, 0.98950400844729336}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.64910632347157293, 0.97130674807898676}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.64910632347157293, 0.55011276448004953}", + "curveMode": 1, + "curveTo": "{0.64910632347157293, 0.55011276448004953}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.64910632347157293, 0.55011276448004953}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 47, + "width": 25, + "x": 24, + "y": 14 + }, + "id": "85D93FCD-5A69-4DAF-AE90-351CD9B64554", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "7DEDDC31-9455-4677-8F90-529CB41EA4D5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 12.70833333333333, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Invite Friends Button", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 342, + "x": 36, + "y": 699 + }, + "id": "A6BFF201-765E-463B-99BC-F46EAFE2D98C", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "1832B4C7-3001-4C3E-AA08-D3D2E1D142C9", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 342, + "x": 0, + "y": 0 + }, + "id": "E9996286-0EBA-4D08-BEB5-B9A49B768BCD", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "DECF2495-AFB7-4E53-B934-927950CE85B5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Rectangle 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": true, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 30.5, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 30.5, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 30.5, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 30.5, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 100, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 342, + "x": 0, + "y": 0 + }, + "id": "C814E39E-06A4-4B97-A3C8-F86455BA308F", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "87845F2D-AC40-4B49-A94D-E07F37813671", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + }, + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.45, + "blue": 0.8901960784313725, + "green": 0.788235294117647, + "red": 0.09411764705882357 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 0.5, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Invite Friends", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Invite Friends", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 14, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "paragraphSpacing": 2.299999952316284, + "alignment": 0 + }, + "MSAttributedStringTextTransformAttribute": 1 + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {136, 14}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 138, + "x": 88, + "y": 21 + }, + "id": "C6E0225C-65AE-4FB2-B210-A17CC2682AD3", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "C0CD0577-47B5-45C9-B3F4-CDD7B4ED3CC5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0, 0}", + "gradientType": 0, + "to": "{1, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.9137254901960784, + "green": 0.3529411764705881, + "red": 0.3568627450980389 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.9411764705882353, + "green": 0.4549019607843137, + "red": 0.2784313725490197 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "MSAttributedStringTextTransformAttribute": 1, + "paragraphStyle": { + "_class": "paragraphStyle", + "paragraphSpacing": 2.299999952316284, + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "svg", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Spotify Copy", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 61, + "x": 0, + "y": 0 + }, + "id": "93AAA72A-7FA3-48F9-A329-6CAF4B38DF42", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "120EB29A-683F-4BC9-9554-3B680A035A54", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10.16666666666667, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Spotify", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "constraints": { + "scaleFactor": 1, + "model_version": 0.1, + "aspectRatio": { + "model_version": 0.1, + "enabled": 1, + "multiplier": 48, + "modelID": "constraint_4e4d9c72-56cb-4f9a-945e-5cb658c0a3a5", + "model_class": "ADModelConstraint", + "constant": 48 + }, + "modelID": "viewConstraints_4cbb1bd9-ccf1-4576-98f5-e7917524f2ad", + "model_class": "ADModelViewConstraints", + "automatic": 1 + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": false, + "pointRadiusBehaviour": 0, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22386215049526231, 0}", + "curveMode": 4, + "curveTo": "{0.49999701469367769, 0}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.49999701469367769, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77615576134267139}", + "curveMode": 2, + "curveTo": "{0, 0.22385617988261777}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.49999104408103312}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614382011738225, 1}", + "curveMode": 2, + "curveTo": "{0.22386215049526231, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.49999701469367769, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385617988261777}", + "curveMode": 2, + "curveTo": "{1, 0.77615576134267139}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.49999104408103312}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.49999701469367769, 0}", + "curveMode": 4, + "curveTo": "{0.77614382011738225, 0}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.49999701469367769, 0}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 61, + "width": 61, + "x": 0, + "y": 0 + }, + "id": "43CFDC5E-F7CC-4BAF-BC12-B9F65072D434", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "BE2C0514-12B3-4F05-99C6-B3846D2801FC", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10.16666666666667, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.8901960784313725, + "green": 0.788235294117647, + "red": 0.09411764705882357 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7058823529411764, + "green": 0.9019607843137255, + "red": 0 + } + }, + { + "_class": "gradientStop", + "position": 0.9736497471098265, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.8901960784313725, + "green": 0.788235294117647, + "red": 0.09411764705882357 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 29, + "width": 44, + "x": 9, + "y": 17 + }, + "id": "B25B2498-2C8B-4172-9BF9-A26EACA7E727", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "41EE6ED1-6230-4E6A-918A-93E21B4D71C9", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 12.70833333333333, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Fill 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 1.270833333333333, + "curveFrom": "{0, 0.4789936305732484}", + "curveMode": 1, + "curveTo": "{0, 0.4789936305732484}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0.4789936305732484}" + }, + { + "_class": "curvePoint", + "cornerRadius": 1.270833333333333, + "curveFrom": "{0.49999999999999994, 1}", + "curveMode": 1, + "curveTo": "{0.49999999999999994, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.49999999999999994, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 1.270833333333333, + "curveFrom": "{1, 0.5}", + "curveMode": 1, + "curveTo": "{1, 0.5}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 1.270833333333333, + "curveFrom": "{0.49999999999999994, 0}", + "curveMode": 1, + "curveTo": "{0.49999999999999994, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.49999999999999994, 0}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 18, + "width": 44, + "x": 0, + "y": 0 + }, + "id": "7B094F2E-5C0E-4BDD-909A-9826BE39B7C0", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "90C12C14-8A60-462F-BD67-79DB53E191E7", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 12.70833333333333, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Fill 6", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.86054967213375011}", + "curveMode": 4, + "curveTo": "{0, 0.68853500150834324}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0, 0.68853500150834324}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77620899273245914, 1}", + "curveMode": 2, + "curveTo": "{0.22385892820756628, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.49999999999999989, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.68853500150834324}", + "curveMode": 4, + "curveTo": "{1, 0.86054967213375011}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{1, 0.68853500150834324}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.014813521108870532}", + "curveMode": 1, + "curveTo": "{1, 0.014813521108870532}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0.014813521108870532}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.49935475106975474, 0.38924789228839557}", + "curveMode": 1, + "curveTo": "{0.49935475106975474, 0.38924789228839557}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.49935475106975474, 0.38924789228839557}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 14, + "width": 26, + "x": 9, + "y": 15 + }, + "id": "7E6BAF73-2733-475D-9715-32721DD88B45", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "58D910A6-BD77-49F6-B533-DD9FAA672157", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 12.70833333333333, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 82, + "width": 85, + "x": 166, + "y": 44 + }, + "id": "66464E42-E480-4BF4-B3B3-43919A5DA6CF", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/d4e1ba0e5ea98dbe54bcfaebd1aefde4182cbcb9.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "10C18FD1-2A0A-4720-98EC-C93BDB18AC4D", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "normal", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.bohemiancoding.sketchtool.detach": { + "symbolInstance": { + "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 93, + "width": 375, + "x": 0, + "y": 724 + } + }, + "symbolMaster": { + "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", + "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" + } + }, + "com.sketch.detach": { + "symbolInstance": { + "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 93, + "width": 375, + "x": 0, + "y": 724 + } + }, + "symbolMaster": { + "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", + "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 322, + "x": 46, + "y": 816 + }, + "id": "BBB88857-820C-4AF2-8D41-3040470884C3", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E48C7801-74D7-4DF2-93B9-FE2DCD3DCD08", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "homeicon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 26, + "width": 28, + "x": 0, + "y": 19 + }, + "id": "CA563D31-03EB-402B-B97F-26BE27CD703C", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/724477925ebd536321fbadee7e227cfd057eb0f5.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E267727C-05B9-4253-B17D-D4AB347AF316", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7294117647058823, + "green": 0.6235294117647059, + "red": 0.5843137254901961 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "BBD21E46-AD9D-4372-AE85-42558046DA42", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "stats", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "BBD21E46-AD9D-4372-AE85-42558046DA42", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 26, + "width": 26, + "x": 222, + "y": 21 + }, + "id": "14151DE3-E3BA-467F-AAF8-F55CC02C1B70", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/791dd23b4cf727cd2ad676896de2196a29d57e2d.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "8DFFC13B-ACB5-49BF-A628-6BBAB8DF0797", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "plus-icon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 61, + "width": 54, + "x": 130, + "y": 0 + }, + "id": "786574C6-2F8C-49B7-936B-B20B9E90F7E7", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/c4eea6263c1c1732dcb7a96694a80dd390a1ff7d.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "5BAB6305-36A1-4EFE-9EE8-0FC60C1E57D8", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "22155B2E-9044-4DCD-A0D1-C5656655323A", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "not published", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "22155B2E-9044-4DCD-A0D1-C5656655323A", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 25, + "width": 25, + "x": 74, + "y": 20 + }, + "id": "86F1F154-0A1B-40FE-823F-BCF2CF3AA063", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5c0161e4cd699ec44a35f72b3b4b529f464c6f94.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "46C2AD45-50F0-4AB4-AC4D-CECEF1D7763C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "learn", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 23, + "width": 26, + "x": 296, + "y": 25 + }, + "id": "A8D88F06-7DC0-4CC6-8A19-1DD50BCEED21", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5ce1816426a25e74eb636fbaa1e06a6627b7d7ee.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "0093DCA4-F75F-4D01-B1E2-99E27AE276C1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "CLASS_NAME": null, + "type": "artboard", + "includeInCloudUpload": true, + "includeBackgroundColorInExport": true, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "layout": null, + "grid": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 896, + "width": 414, + "x": 1165, + "y": -295 + }, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "id": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", + "hasBackgroundColor": false, + "isFlowHome": false, + "resizesContent": false, + "presetDictionary": { + "name": "iPhone 11", + "offersLandscapeVariant": 1, + "height": 896, + "allowResizedMatching": 1, + "width": 414 + }, + "visible": true, + "style": { + "_class": "style", + "do_objectID": "392B71E3-523A-43F7-8AAA-1ECDAD54DF46", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "artboard" + }, + "azure_blob_uri": "/B8F978E3-16B6-4278-B836-B67E3F123C68.png" + }, + { + "pbdfType": "screen", + "id": "24a06315-fbdb-489c-a4e5-5359ca2a4217", + "name": "person/4", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "LearningOverviewAlt", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "header", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.bohemiancoding.sketchtool.detach": { + "symbolInstance": { + "do_objectID": "941D602A-D496-4CC2-8F15-A1E5FFB77A4A", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 414, + "x": 0, + "y": 0 + } + }, + "symbolMaster": { + "do_objectID": "ADF19C17-3F52-4FE3-B207-2A6E6AC2DB95", + "symbolID": "65B0D541-BC41-4E38-81E3-41E0946BC70B" + } + }, + "com.sketch.detach": { + "symbolInstance": { + "do_objectID": "941D602A-D496-4CC2-8F15-A1E5FFB77A4A", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 414, + "x": 0, + "y": 0 + } + }, + "symbolMaster": { + "do_objectID": "ADF19C17-3F52-4FE3-B207-2A6E6AC2DB95", + "symbolID": "65B0D541-BC41-4E38-81E3-41E0946BC70B" + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 414, + "x": 0, + "y": 0 + }, + "id": "94F89071-B4F6-410D-887D-AF082F7F2C80", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4BAE7A62-A55F-4322-98D2-0CB40395AA2C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 0, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 95, + "width": 414, + "x": 0, + "y": 0 + }, + "id": "5DC9BD8F-C5ED-4866-A4D9-B27BF479B241", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "356D8E5E-352A-48F0-AB1E-D8A1774C9BCC", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.2078431372549019 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.207843137254902 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "userScore", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 25, + "width": 78, + "x": 168.912, + "y": 51 + }, + "id": "7D00B6BE-0E2D-4070-A030-361C8467375D", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F36367EC-10F0-4B0B-AFF1-135E96329ACE", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "285", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "285", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 3, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 21 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 5}, {38, 16}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 25, + "width": 40, + "x": 0, + "y": 0 + }, + "id": "6E819171-9A2D-4637-91E2-E78320280444", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "006F588A-0F39-497A-8702-4C700E08FCFB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Bold", + "size": 21 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle" + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "starIcon", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 22, + "width": 24.28799999999999, + "x": 52.99199999999998, + "y": 2 + }, + "id": "0053C932-F835-458F-B0E3-3FD7DFF564BA", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/7dc57eea260f608d09f997083c71f337eda203ca.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "CB5342B7-5060-4079-B9C9-01BF7CBACD67", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "bellIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 29.2258064516129, + "width": 27.77806451612903, + "x": 18.76799999999998, + "y": 48.77419354838709 + }, + "id": "26DB7CAC-F3BE-4511-ACFF-F47617244758", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/1ab87eea21615010a2576c5a46416a88641231ec.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "988FD171-E4E6-4587-B377-FAF3DC822820", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "profileIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 34, + "width": 37.536, + "x": 359.904, + "y": 48 + }, + "id": "76846784-DD7F-41D6-B842-655F40CC327D", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6B81B647-BA5A-4554-AB36-4CE64E56074C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Categories", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Categories", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 10, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{0, 3}, {87, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 88, + "x": 23, + "y": 160 + }, + "id": "CCA8F746-FCF4-4A56-ABC7-407A352099E3", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "7794BFC0-9651-48EB-888C-3D5E7C73AC8D", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "1. Bars / 2. Top Bar / 2. Large / Heading + Search", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 40, + "width": 126, + "x": 22, + "y": 113 + }, + "id": "1E78D0AA-8AAA-4388-AD04-59D2AD9E874E", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "1E08EB87-015B-4E84-9B22-067ED7AA7E06", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "🅰️ Heading", + "nameIsFixed": true, + "resizingConstraint": 41, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": "4475D330-67E5-4F54-AA9A-872C355EA16D", + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.invisionlabs.duplicate": { + "type-duplicate": { + "title": "Advertising", + "action": "article", + "options": { + "section": "advertising", + "type": "title" + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Explore", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 7, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 32 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.3618807196617126, + "green": 0.1713331937789917, + "red": 0.01447581406682729 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "maximumLineHeight": 40, + "minimumLineHeight": 40, + "alignment": 0 + }, + "kerning": 0.6240000000000001 + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{2, 7}, {122, 30}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 40, + "width": 126, + "x": 0, + "y": 0 + }, + "id": "BA34833A-44CE-40E8-9355-C9271E255038", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6D5E548A-28B5-4C96-AE1C-D9ED3ACABCFB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 32 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.3618807196617126, + "green": 0.1713331937789917, + "red": 0.01447581406682729 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "maximumLineHeight": 40, + "minimumLineHeight": 40, + "alignment": 0 + }, + "kerning": 0.6240000000000001 + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 155, + "width": 105, + "x": 22, + "y": 198 + }, + "id": "3BB30F81-45EF-4A63-97F8-0845A49DB6B3", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B351B8F7-FDFF-4E4E-A2CC-E3C89C1D2111", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 155, + "width": 105, + "x": 0, + "y": 0 + }, + "id": "D6902730-8775-4EC7-94F0-7E454B33AAAE", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "461E8C70-9CD6-402F-A5F6-E3A36D081DEB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 8, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 155, + "width": 105, + "x": 0, + "y": 0 + }, + "id": "5FDDFB6C-067B-4B27-B14F-D157469D2773", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "246896A3-5690-46F5-A399-6A2274561287", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.2078431372549019 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.207843137254902 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Careers", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Careers", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 7, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 4}, {59, 13}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 61, + "x": 22, + "y": 129 + }, + "id": "AA8CE149-92C3-4A7A-92F8-F6C3F06F5601", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "CA8F670B-99F1-4D7C-907B-F29C73F8894F", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "simplePaperIcon", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 74, + "width": 73, + "x": 16, + "y": 28 + }, + "id": "556125DB-7C28-42D8-B4E1-C1FB5BFC479B", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/fd293ef7fd2f13ffb9962408e16bb189809d7d33.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "98F39059-25E0-4B98-BCD2-2854F2AEF17B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 2 Copy", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 155, + "width": 105, + "x": 155, + "y": 198 + }, + "id": "8B925AFE-DBB6-4DE6-B807-89B1D9C0DD70", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "743111D8-51FE-4561-A2B1-C85A7D91EFFC", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 155, + "width": 105, + "x": 0, + "y": 0 + }, + "id": "30604AF7-A9DF-4A98-9F19-86B9B15BFA0C", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "0EE05200-FDBC-4F15-9EEE-B3D5F888897C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 8, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 155, + "width": 105, + "x": 0, + "y": 0 + }, + "id": "CD086050-0F04-4404-8021-FA787172B16A", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "0F081EEA-B180-426B-9FE7-C6D9F4B3FBBB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.2078431372549019 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.207843137254902 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Majors", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Majors", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 6, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {51, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 53, + "x": 27, + "y": 129 + }, + "id": "68EC2E9C-9285-494E-BB94-1B8C31978B2F", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "BEEB30F6-28E4-4113-987D-8459D65ED1C1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "simplePaperIcon", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 74, + "width": 73, + "x": 16, + "y": 28 + }, + "id": "9B3D1988-167F-47DA-9885-DD0F0AD2321D", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/fd293ef7fd2f13ffb9962408e16bb189809d7d33.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "1C319D1E-567D-4B9A-B8FB-F8C6CB2F9A8F", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 2 Copy 2", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 155, + "width": 105, + "x": 288, + "y": 198 + }, + "id": "7023E57E-5505-4B7E-8E77-766F979B5A53", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "25D09D8C-02AD-4EA0-B1D0-A96F0D19B5BD", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 155, + "width": 105, + "x": 0, + "y": 0 + }, + "id": "4B552FC8-0C31-4DE8-91A6-57EA9CDC9776", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "5558C7E0-9E63-4057-87AA-960C9F3CAEF9", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 8, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 155, + "width": 105, + "x": 0, + "y": 0 + }, + "id": "9EEA394B-09DE-4B73-90B8-19554FD98998", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "660D914F-4351-4C98-8C65-565079F5D0BB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.984313725490196, + "green": 0.596078431372549, + "red": 0.2078431372549019 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{1, 1}", + "gradientType": 0, + "to": "{0, 0}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.9115715579710145, + "green": 0.8498216172586106, + "red": 0.7880716765462067 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7647058823529411, + "green": 0.3372549019607842, + "red": 0.2117647058823529 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Colleges", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Colleges", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 8, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 4}, {65, 16}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 67, + "x": 19, + "y": 129 + }, + "id": "3A5EF981-4C73-4B5C-9FFA-3315C5C94466", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "AE2508FA-F195-40A8-B287-BB5D904F444C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "simplePaperIcon", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 74, + "width": 73, + "x": 16, + "y": 28 + }, + "id": "9FB103B3-C1A8-4B8C-8EEC-927880C7CB59", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/fd293ef7fd2f13ffb9962408e16bb189809d7d33.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "519ABD12-BB51-42DF-8162-9A26D08501A7", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Continue Learning", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Continue Learning", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 17, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{0, 3}, {148, 17}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 149, + "x": 23, + "y": 371 + }, + "id": "E1153CD7-8B2B-4059-8C78-F62760268383", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "085CC7D2-A9A1-430C-BB36-C3872168B06E", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "View All", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "View All", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 8, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 14 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.9490196078431372, + "green": 0.5568627450980396, + "red": 0.211764705882353 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{0, 2}, {52, 12}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 16, + "width": 53, + "x": 340, + "y": 375 + }, + "id": "99B6F452-E659-4BFE-9686-B11E3E4EDC1E", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "068F3D4D-CF71-432E-9B29-B280BAA8363E", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 14 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.9490196078431372, + "green": 0.5568627450980396, + "red": 0.211764705882353 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Lesson Big Card", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 31, + "y": 419 + }, + "id": "9DB70E49-FE27-4056-92F2-EC99F0194E73", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B3FB6F58-DCD4-4A0A-B9E2-E012F9AAACE1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "6E30FE6F-1084-4C92-B3B5-1D65881E5435", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "05F02B59-BAAA-4539-90ED-3DBC6925F8F9", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 8, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "4D4F8F46-0F68-4C04-8693-EBAA0C4A47AF", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "A36E5F42-2A53-49FB-AF4E-292C528EDEB5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7725490196078432, + "green": 0.2117647058823529, + "red": 0.4980392156862745 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{-0.011826262394689041, 0.081614891851427465}", + "gradientType": 0, + "to": "{0.92197160979761905, 0.86807351602486948}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7725490196078432, + "green": 0.211764705882353, + "red": 0.4978553921568629 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.6625905797101449, + "green": 0.3741338919312257, + "red": 0.5905552038449001 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Fundamentals of Algo", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Fundamentals\nof Algorithms", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 26, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {120, 37}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 40, + "width": 121, + "x": 22, + "y": 14 + }, + "id": "DF4BD58E-35FB-408A-9535-F39342546684", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E0231EF1-6D28-4FE4-B834-AEB4C87A8D68", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "paperIcon", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 97, + "width": 97, + "x": 34, + "y": 74 + }, + "id": "22F842A2-E6E1-4AA0-AA65-618A000F87B3", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/83c10f3fe733b88aca886ce5f9ba40355d502171.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "1FC55A62-6D34-4663-9199-549A2C33958B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 5", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 218, + "y": 419 + }, + "id": "BE00E55E-048D-4CFB-8DFD-C45A55AEA88D", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "74C27C5B-059C-4037-8BD0-1F9FF646A7E4", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Lesson Big Card Copy", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "6F732523-C652-42A1-A416-2718BCB64AEA", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4E4D066F-3B75-4453-9B69-939313F030A1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "415D8464-E46A-4B69-B567-6E9302F915EE", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "100391D6-1F8C-4342-8436-AF0D380ACEF1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 8, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "B6054139-473E-4021-B65F-D2A93E28C0F2", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "042E3055-9E33-449F-92D0-0A960B8229BA", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.85, + "blue": 0, + "green": 0, + "red": 0 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{-0.011826262394689041, 0.081614891851427465}", + "gradientType": 0, + "to": "{0.92197160979761905, 0.86807351602486948}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7725490196078432, + "green": 0.211764705882353, + "red": 0.4978553921568629 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.6625905797101449, + "green": 0.3741338919312257, + "red": 0.5905552038449001 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Finance", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Finance", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 7, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 2}, {65, 15}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 67, + "x": 49, + "y": 14 + }, + "id": "D1379E19-80E5-4D48-9B86-ED8A4547E852", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6EC85059-B120-4775-B0C9-BA7DBA01872F", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "cashIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 93, + "width": 132, + "x": 16, + "y": 74 + }, + "id": "089F3BA8-2C99-48B6-83E3-DA903D8D9973", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5ba1a8495a66eacb0d83c6546dc05ec1cc687e67.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "04BD411A-5419-4863-8F71-9784E5A52487", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Lessons", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Lessons", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 7, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 4}, {64, 13}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 66, + "x": 36, + "y": 626 + }, + "id": "91C8C1DE-74EB-4F19-BC19-C02F5A3F65F5", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B374B44E-727F-47EF-BFAD-15E5260D2354", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Semibold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 0.04472257653061224, + "green": 0.04472257653061224, + "red": 0.04472257653061224 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Lesson Big Card", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 31, + "y": 664 + }, + "id": "6182EE5C-B95D-4224-A85E-46BE5E126B06", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "C16F2315-8D16-4C61-BADA-2975863F4680", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "210B3FA3-DEBF-4E9C-BEFA-531E3EB4BE18", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E87DEB8D-C8CA-48F2-8396-A9033FD46E32", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 8, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "A1CDA745-DA2D-4D2F-AAB5-4A1C14C0EFFC", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "204D36A5-9F12-4648-B5D7-763992C40C37", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7725490196078432, + "green": 0.2117647058823529, + "red": 0.4980392156862745 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{-0.011826262394689041, 0.081614891851427465}", + "gradientType": 0, + "to": "{0.92197160979761905, 0.86807351602486948}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7725490196078432, + "green": 0.211764705882353, + "red": 0.4978553921568629 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.6625905797101449, + "green": 0.3741338919312257, + "red": 0.5905552038449001 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Fundamentals of Algo", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Fundamentals\nof Algorithms", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 26, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 3}, {120, 37}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 40, + "width": 121, + "x": 22, + "y": 14 + }, + "id": "861A0370-C107-4A5F-AD75-B4A574FA5F82", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B2099770-8646-43D4-91FF-2BDA6DD33C6E", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "paperIcon", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 97, + "width": 97, + "x": 34, + "y": 74 + }, + "id": "51675CD4-5EC9-49FB-8B8E-F60F22743F0B", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/83c10f3fe733b88aca886ce5f9ba40355d502171.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "CD446D7A-3119-470F-996A-1661A8E58397", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 5", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 218, + "y": 664 + }, + "id": "503CC118-F6CD-45B9-8F3E-A8CE21F5857B", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "49CE6C0A-59E1-4924-B9CE-FD13BB79D1DB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Lesson Big Card Copy", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "98061207-A8DB-446F-91DC-C115C01AD741", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "93C7447F-3FFB-47F7-B322-F4F952251B3A", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 4", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "947F75F5-F92E-4428-9ABB-93D8D30DE80F", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "FCE1128D-D7FD-4283-917B-5C5D366D077D", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Background", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 8, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 8, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 200, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "385B396A-DA82-4C16-B355-AAB244BF7CF4", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B1FFD055-C4B2-4803-B391-351493E0B147", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.85, + "blue": 0, + "green": 0, + "red": 0 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{-0.011826262394689041, 0.081614891851427465}", + "gradientType": 0, + "to": "{0.92197160979761905, 0.86807351602486948}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7725490196078432, + "green": 0.211764705882353, + "red": 0.4978553921568629 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.6625905797101449, + "green": 0.3741338919312257, + "red": 0.5905552038449001 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Finance", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Finance", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 7, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 0, + "glyphBounds": "{{1, 2}, {65, 15}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 20, + "width": 67, + "x": 49, + "y": 14 + }, + "id": "4E39823B-DF29-4C6C-B7E3-7183B3B446AC", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B81E06BD-EF4D-436A-BE3D-9BE0EC2DEB85", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFProText-Bold", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "textStyleVerticalAlignmentKey": 0, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 2 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "cashIcon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 93, + "width": 132, + "x": 16, + "y": 74 + }, + "id": "A64B057B-A87C-44A1-A263-AE547B29543A", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5ba1a8495a66eacb0d83c6546dc05ec1cc687e67.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "EF6365AE-8330-4433-9A3C-59D9D18ED42E", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + } + ], + "pbdfType": "group" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 1, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@2x", + "namingScheme": 0, + "scale": 2, + "visibleScaleType": 0 + }, + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "@3x", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "normal", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.bohemiancoding.sketchtool.detach": { + "symbolInstance": { + "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 93, + "width": 375, + "x": 0, + "y": 724 + } + }, + "symbolMaster": { + "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", + "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" + } + }, + "com.sketch.detach": { + "symbolInstance": { + "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", + "frame": { + "_class": "rect", + "constrainProportions": false, + "height": 93, + "width": 375, + "x": 0, + "y": 724 + } + }, + "symbolMaster": { + "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", + "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 61, + "width": 322, + "x": 47, + "y": 818 + }, + "id": "4465305C-8C87-48DC-B662-AF658EB7713F", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "9E862139-C397-4E51-956B-47F67F411ADD", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "homeicon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 26, + "width": 28, + "x": 0, + "y": 19 + }, + "id": "144F29D7-8F19-4AAF-8CBF-4E123EC8176C", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/724477925ebd536321fbadee7e227cfd057eb0f5.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "603BEA0F-3C21-42DC-A944-66DA717E6A5D", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7294117647058823, + "green": 0.6235294117647059, + "red": 0.5843137254901961 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "BBD21E46-AD9D-4372-AE85-42558046DA42", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "stats", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "BBD21E46-AD9D-4372-AE85-42558046DA42", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 26, + "width": 26, + "x": 222, + "y": 21 + }, + "id": "3CF02E70-7943-4864-A26D-6E77EE3904BE", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/791dd23b4cf727cd2ad676896de2196a29d57e2d.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E0029D22-7647-4AF3-8535-4C5859A0537F", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "plus-icon", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 59.89090909090909, + "width": 52.56, + "x": 130.72, + "y": 0.7393939393939394 + }, + "id": "1BE4D5A9-58A4-4813-8FE0-E6D556B7476F", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/a760f6e1fcbe5bc9ee36e6c2a56110bbac66b4ed.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "7EB73318-7DFE-45F8-AE16-7B65D73AB592", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": { + "_class": "MSImmutableFlowConnection", + "destinationArtboardID": "22155B2E-9044-4DCD-A0D1-C5656655323A", + "maintainScrollPosition": false, + "animationType": 0 + }, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "not published", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": "22155B2E-9044-4DCD-A0D1-C5656655323A", + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 25, + "width": 25, + "x": 74, + "y": 22 + }, + "id": "0B199A09-DD5D-46B8-9780-8862CD2CAE4D", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5c0161e4cd699ec44a35f72b3b4b529f464c6f94.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "05D5063F-57D2-4417-8EB8-1D694968EB96", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "learn", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 72, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 23, + "width": 26, + "x": 296, + "y": 25 + }, + "id": "92D28B96-2E46-4AE8-9195-566E1F8BE291", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/5ce1816426a25e74eb636fbaa1e06a6627b7d7ee.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "4FA8E9BA-59DC-48D4-96FF-D177877339A1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "CLASS_NAME": null, + "type": "artboard", + "includeInCloudUpload": true, + "includeBackgroundColorInExport": true, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "layout": null, + "grid": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 896, + "width": 414, + "x": 176, + "y": -295 + }, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "id": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", + "hasBackgroundColor": false, + "isFlowHome": false, + "resizesContent": false, + "presetDictionary": { + "height": 896, + "offersLandscapeVariant": 1, + "width": 414, + "allowResizedMatching": 1, + "name": "iPhone 11" + }, + "visible": true, + "style": { + "_class": "style", + "do_objectID": "C17C3CAE-EFDC-4347-B3C1-644A4A629510", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "artboard" + }, + "azure_blob_uri": "/24A06315-FBDB-489C-A4E5-5359CA2A4217.png" + }, + { + "id": "c756078b-9e00-45cf-8978-050e04f39e68", + "name": "person/frame", + "convert": true, + "azure_blob_uri": "/C756078B-9E00-45CF-8978-050E04F39E68.png", + "type": "symbolMaster" + }, + { + "id": "277a3d19-a01b-4e11-8f57-7c6d9b49749c", + "name": "person/1", + "convert": true, + "azure_blob_uri": "/277A3D19-A01B-4E11-8F57-7C6D9B49749C.png", + "type": "symbolMaster" + }, + { + "id": "ac76fba2-f9ca-4dee-94ed-03918f4ce652", + "name": "person/5", + "convert": true, + "azure_blob_uri": "/AC76FBA2-F9CA-4DEE-94ED-03918F4CE652.png", + "type": "symbolMaster" + }, + { + "id": "14464801-56ae-4b2e-888b-b7c56bb513dc", + "name": "person/12", + "convert": true, + "azure_blob_uri": "/14464801-56AE-4B2E-888B-B7C56BB513DC.png", + "type": "symbolMaster" + }, + { + "id": "2c9ab975-28fc-40c1-ad16-a32bba023e53", + "name": "person/withframe", + "convert": true, + "azure_blob_uri": "/2C9AB975-28FC-40C1-AD16-A32BBA023E53.png", + "type": "symbolMaster" + }, + { + "id": "d377e55e-2dc6-446a-ac51-4c913a2b5692", + "name": "someElement/green", + "convert": true, + "azure_blob_uri": "/D377E55E-2DC6-446A-AC51-4C913A2B5692.png", + "type": "symbolMaster" + }, + { + "id": "d5f9ba19-3b15-490c-b31b-24aa26d8b77b", + "name": "someElement/default", + "convert": true, + "azure_blob_uri": "/D5F9BA19-3B15-490C-B31B-24AA26D8B77B.png", + "type": "symbolMaster" + } + ] + }, + { + "pbdfType": "design_page", + "id": "e6289062-5385-4b33-895f-3903b00ac1b5", + "name": "Index Screens", + "convert": false, + "screens": [ + { + "pbdfType": "symbol_master", + "id": "22155b2e-9044-4dcd-a0d1-c5656655323a", + "name": "Majors Overview", + "convert": false, + "type": "artboard", + "designNode": { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "SmallMajorCard", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [ + { + "overrideName": "44671E81-67A4-4092-BA3A-85BD386E3A0D_stringValue", + "canOverride": true + } + ], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 965, + "y": 0 + }, + "id": "A1CA9316-82B5-4270-B143-97575F0EC1D0", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "7B52A67B-CC26-49DC-BA57-A44E36BB3DD5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group Copy 3", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "5902329C-3987-4B23-8498-975E7C0C1C1A", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "22D3F25F-BE59-41C5-ADBF-CF9EB43BC581", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 10, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 10, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 80, + "width": 165, + "x": 0, + "y": 0 + }, + "id": "6B9C49AF-B62C-4301-AC20-7FA7EAD3CCCA", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "234CE166-E055-486A-9081-9F910352A40D", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7686274509803921, + "green": 0.3411764705882353, + "red": 0.2117647058823529 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.10430849801947592, 0.14482966241182565}", + "gradientType": 0, + "to": "{0.87787832789057207, 0.86568038915591661}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.7686274509803922, + "green": 0.3411764705882352, + "red": 0.2117647058823529 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.9764705882352941, + "green": 0.5843137254901962, + "red": 0.2078431372549021 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Information Systems", + "nameIsFixed": false, + "resizingConstraint": 47, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "isAutoWidth": 1 + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "attributedString": { + "_class": "attributedString", + "string": "Information Systems", + "attributes": [ + { + "_class": "stringAttribute", + "location": 0, + "length": 19, + "attributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + } + } + ] + }, + "automaticallyDrawOnUnderlyingPath": false, + "dontSynchroniseWithSymbol": false, + "lineSpacingBehaviour": 2, + "textBehaviour": 1, + "glyphBounds": "{{0, 3}, {92, 37}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 40, + "width": 117, + "x": 12, + "y": 13 + }, + "id": "44671E81-67A4-4092-BA3A-85BD386E3A0D", + "type": "text", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6323C2AB-75FD-4223-8817-F8AA75985F86", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": { + "encodedAttributes": { + "MSAttributedStringFontAttribute": { + "_class": "fontDescriptor", + "attributes": { + "name": "SFCompactText-Regular", + "size": 17 + } + }, + "MSAttributedStringColorAttribute": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "paragraphStyle": { + "_class": "paragraphStyle", + "alignment": 0 + } + }, + "fontFamily": null, + "fontSize": null, + "fontWeight": null, + "weight": null + } + }, + "pbdfType": "text" + } + ], + "pbdfType": "group" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/22155B2E-9044-4DCD-A0D1-C5656655323A.png" + }, + { + "pbdfType": "symbol_master", + "id": "36eb4ce8-41dd-4ede-a4bd-ed88d043d9f1", + "name": "Landing Page", + "convert": false, + "type": "artboard", + "designNode": { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "icons/tabbar/home", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "7C0DA89B-7956-40D4-AB6D-1A0DB5D53C20", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [ + { + "overrideName": "B12B62C2-D7E3-452E-963E-A24216DD0942_layerStyle", + "canOverride": true + } + ], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 32, + "width": 32, + "x": 100, + "y": 264 + }, + "id": "7ABB7146-7156-4FA4-8E2D-F816FD51ED27", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "00BDA43A-F7B4-47FE-BB00-50DF3342D4D1", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Oval", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "constraints": { + "scaleFactor": 1, + "model_version": 0.1, + "aspectRatio": { + "model_class": "ADModelConstraint", + "enabled": 1, + "multiplier": 26, + "constant": 26, + "model_version": 0.1, + "modelID": "constraint_b463a532-3d93-4801-baa5-bb66b2d2925f" + }, + "modelID": "viewConstraints_bf976398-3916-4b68-89f2-37e4bd211879", + "model_class": "ADModelViewConstraints", + "automatic": 1 + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614237490000004, 1}", + "curveMode": 2, + "curveTo": "{0.22385762510000001, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385762510000001}", + "curveMode": 2, + "curveTo": "{1, 0.77614237490000004}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22385762510000001, 0}", + "curveMode": 2, + "curveTo": "{0.77614237490000004, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77614237490000004}", + "curveMode": 2, + "curveTo": "{0, 0.22385762510000001}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 24, + "width": 24, + "x": 4, + "y": 4 + }, + "id": "0750E655-B2B6-4BF4-BB79-FE199ADCD442", + "type": "oval", + "visible": false, + "style": { + "_class": "style", + "do_objectID": "F2159235-3DCD-4F24-817E-8BB87663592D", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 0.3065243675595238 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "oval" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [ + { + "_class": "exportFormat", + "absoluteSize": 0, + "fileFormat": "png", + "name": "", + "namingScheme": 0, + "scale": 3, + "visibleScaleType": 0 + } + ] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Shape", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": "10B8A524-8E34-4194-AF07-EFBC51AE2411", + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "windingRule": 1, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 21, + "width": 23.33333333333334, + "x": 4, + "y": 6 + }, + "id": "B12B62C2-D7E3-452E-963E-A24216DD0942", + "type": "shapeGroup", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "A276C6C9-ECE5-4AB0-9828-BAF0748FD5BA", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.65, + "green": 0.56615, + "red": 0.533 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Path", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.49450108835277012, 7.4490142024652428e-06}", + "curveMode": 2, + "curveTo": "{0.5055762181935034, 2.157848065534318e-05}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.48424479999999998, 0.0074462875000000095}", + "curveMode": 4, + "curveTo": "{0.48908856784325078, 0.0025655367448264577}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.48424479999999998, 0.0074462875000000095}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.017903645999999999, 0.44458006250000004}", + "curveMode": 1, + "curveTo": "{0.017903645999999999, 0.44458006250000004}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.017903645999999999, 0.44458006250000004}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.0069166546011208436, 0.45545982713662758}", + "curveMode": 4, + "curveTo": "{0.017903645999999999, 0.44470212499999995}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.017903645999999999, 0.44470212499999995}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{2.0452959175910712e-05, 0.5232403048716201}", + "curveMode": 2, + "curveTo": "{2.0452959175910712e-05, 0.4767596951283799}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.017903646000000006, 0.55529787499999994}", + "curveMode": 4, + "curveTo": "{0.0069166546011208436, 0.54454017286337242}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.017903646000000006, 0.55529787499999994}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.017903645999999999, 0.55541993749999996}", + "curveMode": 1, + "curveTo": "{0.017903645999999999, 0.55541993749999996}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.017903645999999999, 0.55541993749999996}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.48893954673107093, 0.9973342343594731}", + "curveMode": 4, + "curveTo": "{0.48404946666666665, 0.99230956250000002}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.48404946666666665, 0.99230956250000002}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.50549891278150572, 0.99999254329967457}", + "curveMode": 4, + "curveTo": "{0.49442378151854688, 0.99997841960312694}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.51575519999999997, 0.99255368750000006}", + "curveMode": 4, + "curveTo": "{0.51091143335753031, 0.99743444694915162}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.51575519999999997, 0.99255368750000006}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.98187957193968611, 0.55558375807325056}", + "curveMode": 4, + "curveTo": "{0.98177083333333337, 0.5556640625}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.98177083333333337, 0.5556640625}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.98209636666666666, 0.55541993749999996}", + "curveMode": 4, + "curveTo": "{0.98198808455141251, 0.55550238194790424}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.98209636666666666, 0.55541993749999996}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.99308335315753915, 0.54454016641966496}", + "curveMode": 4, + "curveTo": "{0.98209636666666666, 0.55529787500000005}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.98209636666666666, 0.55529787500000005}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.99997954950709833, 0.47675970029528714}", + "curveMode": 2, + "curveTo": "{0.99997954950709833, 0.52324029970471286}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.98209636666666666, 0.44470212500000006}", + "curveMode": 4, + "curveTo": "{0.99308335315753915, 0.45545983358033504}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.98209636666666666, 0.44470212500000006}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.98209636666666666, 0.44458006250000004}", + "curveMode": 1, + "curveTo": "{0.98209636666666666, 0.44458006250000004}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.98209636666666666, 0.44458006250000004}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.51106045296356506, 0.0026657615669901102}", + "curveMode": 4, + "curveTo": "{0.51595053333333341, 0.0076904312499999905}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.51595053333333341, 0.0076904312499999905}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 12.44444444444445, + "width": 23.33333333333334, + "x": 0, + "y": 0 + }, + "id": "9907F8CC-2BCC-489A-8C25-B86A4316EC2B", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6F9ACE86-C918-484D-90F1-DEF37A6C6CC5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + }, + { + "booleanOperation": 1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Rectangle", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 63, + "sharedStyleID": "10B8A524-8E34-4194-AF07-EFBC51AE2411", + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0.9, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0.9, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0.9, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0.9, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 0.9, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 9, + "width": 1.8, + "x": 15.70901570946376, + "y": 2.757221642229653 + }, + "id": "ABD43AA3-8BE9-4909-A6B9-040C6C19568A", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "524FEE05-5452-4E6E-81C0-DA9CFDF4B01E", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.65, + "green": 0.5785, + "red": 0.5525 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Path", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.75, 0}", + "curveMode": 1, + "curveTo": "{0.75, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.75, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.25, 0.063912122365638188}", + "curveMode": 1, + "curveTo": "{0.25, 0.063912122365638188}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0.25, 0.063912122365638188}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.10109149999999989, 0.65638369617097347}", + "curveMode": 4, + "curveTo": "{0.25, 0.63425290947154644}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.25, 0.63425290947154644}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.8149744057514775}", + "curveMode": 3, + "curveTo": "{0, 0.69712390336384844}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.7443515105374473}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.5, 1}", + "curveMode": 2, + "curveTo": "{0.5, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.69712390336384844}", + "curveMode": 3, + "curveTo": "{1, 0.8149744057514775}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.7443515105374473}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.75, 0.63425290947154644}", + "curveMode": 4, + "curveTo": "{0.89890850000000011, 0.65638369617097347}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.75, 0.63425290947154644}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 12.16948755555555, + "width": 3.111111111111111, + "x": 20.22222222222222, + "y": 8.830512444444446 + }, + "id": "3EB1B5AD-63BD-45A2-A5BC-DC0DB94FEA88", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "87080C3A-47BE-4994-8866-C69DB8590422", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + }, + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Path", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": true, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.7552587665785131}", + "curveMode": 4, + "curveTo": "{0, 0.45345861227894851}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0, 0.45345861227894851}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77616666666666667, 1}", + "curveMode": 2, + "curveTo": "{0.22383333333333333, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.45345861227894851}", + "curveMode": 4, + "curveTo": "{1, 0.7552587665785131}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{1, 0.45345861227894851}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.57117966666666675, 0.42196930230056767}", + "curveMode": 4, + "curveTo": "{0.57584633333333335, 0.41737835464371065}", + "hasCurveFrom": true, + "hasCurveTo": false, + "point": "{0.57584633333333335, 0.41737835464371065}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.5416293333333333, 0.44519392272210834}", + "curveMode": 4, + "curveTo": "{0.56651822222222215, 0.42573704931923878}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.56174044444444449, 0.42890698936802091}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.47911111111111115, 0.45345861227894851}", + "curveMode": 2, + "curveTo": "{0.52094444444444443, 0.45345861227894851}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0.45345861227894851}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.43364322222222224, 0.42573704931923878}", + "curveMode": 4, + "curveTo": "{0.45847655555555555, 0.44519392272210834}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.43847655555555559, 0.42890698936802091}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.42415366666666671, 0.41716487557766679}", + "curveMode": 4, + "curveTo": "{0.42887588888888889, 0.42186513151206773}", + "hasCurveFrom": false, + "hasCurveTo": true, + "point": "{0.42415366666666671, 0.41716487557766679}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 7.115451777777775, + "width": 14, + "x": 4.666666666666667, + "y": 10.77343711111111 + }, + "id": "AF491D30-B5FE-41DF-869C-AB5314DF7ABA", + "type": "shapePath", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B2C15FB3-E0D0-4505-AE27-341B3F7A64F2", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "vector" + } + ], + "pbdfType": "image" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/36EB4CE8-41DD-4EDE-A4BD-ED88D043D9F1.png" + }, + { + "pbdfType": "symbol_master", + "id": "bbd21e46-ad9d-4372-ae85-42558046da42", + "name": "Community Groups", + "convert": false, + "type": "artboard", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person/6", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "97736C0F-6E1F-4671-912F-003C97ACDE40", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [ + { + "overrideName": "F67563A5-78FC-433D-9E6C-8061F7E2F776_image", + "canOverride": true + } + ], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 1230, + "y": 0 + }, + "id": "53D04C05-9E5D-4F7A-8765-7DBEA892D0B5", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "5341CCB2-B409-4F09-A2E4-5202079F452D", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 11", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "constraints": { + "scaleFactor": 1, + "model_version": 0.1, + "aspectRatio": { + "multiplier": 41, + "enabled": 1, + "model_version": 0.1, + "modelID": "constraint_212aa1aa-8134-4254-9cf4-683c710bd4bb", + "model_class": "ADModelConstraint", + "constant": 41 + }, + "modelID": "viewConstraints_34fef27b-98f3-4757-bfb1-b162b31f962d", + "model_class": "ADModelViewConstraints", + "automatic": 1 + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "9B661BE6-C82B-46A3-B298-E355595772E2", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "323C5208-F3AB-4CE1-AD18-96FA196F6D2E", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Oval", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": true, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614237490000004, 1}", + "curveMode": 2, + "curveTo": "{0.22385762510000001, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385762510000001}", + "curveMode": 2, + "curveTo": "{1, 0.77614237490000004}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22385762510000001, 0}", + "curveMode": 2, + "curveTo": "{0.77614237490000004, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77614237490000004}", + "curveMode": 2, + "curveTo": "{0, 0.22385762510000001}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "F45DE24F-341B-4EBC-8CA9-434FE8C04FB8", + "type": "oval", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "8BE4D1EE-EEEA-418C-BA4F-F4F90AE4DF66", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 5.857142857142858, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 0.5857142857142857 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.0616508152173913, + "blue": 0, + "green": 0, + "red": 0 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "oval" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "MV5BMjAwMzc5OTEzOF5BMl5BanBnXkFtZTgwMDc5ODU3MTE@._V1_UX172_CR0,0,172,256_AL_", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "constraints": { + "scaleFactor": 1, + "model_version": 0.1, + "aspectRatio": { + "model_class": "ADModelConstraint", + "enabled": 1, + "multiplier": 41, + "constant": 61, + "model_version": 0.1, + "modelID": "constraint_ff6a7e0f-e880-4401-882c-d9b53d88e120" + }, + "modelID": "viewConstraints_8ca9ba1e-3c76-47de-80f2-3c91550c3575", + "model_class": "ADModelViewConstraints", + "automatic": 1 + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 0, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 61, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "F67563A5-78FC-433D-9E6C-8061F7E2F776", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/4be294aa4b0e0bdaf4069cdbab5dc3b764fc83c7.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "AE8A5B75-166C-40AA-B758-C932BE85F68A", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/BBD21E46-AD9D-4372-AE85-42558046DA42.png" + }, + { + "pbdfType": "symbol_master", + "id": "3a06138a-40e2-40d7-90cb-56bad609d9ce", + "name": "HomeScreenAlt", + "convert": false, + "type": "artboard", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person/8", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "477112E3-2915-42AA-96E2-BFD71521C33D", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [ + { + "overrideName": "B3428CE0-A493-4780-BF75-94D46A40EE17_image", + "canOverride": true + } + ], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 1230, + "y": 141 + }, + "id": "B8F978E3-16B6-4278-B836-B67E3F123C68", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "0A2BFDE7-7737-4220-8EF2-36CD1B43292E", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 9 Copy", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "3AA512BC-7AF9-4446-9015-3DCB996B0D56", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "ED53BDD5-289B-456C-A347-A72A4CBFEC55", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Oval", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": true, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614237490000004, 1}", + "curveMode": 2, + "curveTo": "{0.22385762510000001, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385762510000001}", + "curveMode": 2, + "curveTo": "{1, 0.77614237490000004}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22385762510000001, 0}", + "curveMode": 2, + "curveTo": "{0.77614237490000004, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77614237490000004}", + "curveMode": 2, + "curveTo": "{0, 0.22385762510000001}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "112378C3-B964-43C7-9CED-E348CBAC77D2", + "type": "oval", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "0C8AC1F3-21BF-41F3-A116-88544B2ABBCA", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 5.857142857142858, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 0.5857142857142857 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.0616508152173913, + "blue": 0, + "green": 0, + "red": 0 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "oval" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "download", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "constraints": { + "scaleFactor": 1, + "model_version": 0.1, + "aspectRatio": { + "model_class": "ADModelConstraint", + "enabled": 1, + "multiplier": 42, + "constant": 42, + "model_version": 0.1, + "modelID": "constraint_3ffbdf65-7ae0-4948-a2e4-14febc075d9b" + }, + "modelID": "viewConstraints_7c165554-f167-4856-bf00-daff5ec0c599", + "model_class": "ADModelViewConstraints", + "automatic": 1 + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 0, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 42, + "width": 42, + "x": -1, + "y": 0 + }, + "id": "B3428CE0-A493-4780-BF75-94D46A40EE17", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/4f1f017d838e74f4de4044aea323e97ae14f8f05.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "FBAD415A-6E7A-4457-8200-D4D906DB680B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/3A06138A-40E2-40D7-90CB-56BAD609D9CE.png" + }, + { + "pbdfType": "symbol_master", + "id": "c1aa2b99-e400-4e44-9000-e19a547ed3b9", + "name": "LearningOverviewAlt", + "convert": false, + "type": "artboard", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person/4", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "29155DF5-855F-4948-9C6C-935F9F9DD81E", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [ + { + "overrideName": "70B94A2C-C684-4AB5-AFE5-4CA194D59039_image", + "canOverride": true + } + ], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 1230, + "y": 282 + }, + "id": "24A06315-FBDB-489C-A4E5-5359CA2A4217", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "7624D8A0-B22B-478B-966A-71253E3532AA", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Group 7", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "708B0958-9512-42A8-A94D-C48381DE30FE", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "47DAA81A-D2B7-40A7-AC07-AEEA7F77140C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Oval", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": true, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614237490000004, 1}", + "curveMode": 2, + "curveTo": "{0.22385762510000001, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385762510000001}", + "curveMode": 2, + "curveTo": "{1, 0.77614237490000004}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22385762510000001, 0}", + "curveMode": 2, + "curveTo": "{0.77614237490000004, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77614237490000004}", + "curveMode": 2, + "curveTo": "{0, 0.22385762510000001}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "07415BF8-21D2-4417-8542-517B64BA3AB9", + "type": "oval", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "0A039717-5343-4BCC-A703-439E5041B1AB", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 5.857142857142858, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 0.5857142857142857 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.0616508152173913, + "blue": 0, + "green": 0, + "red": 0 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "oval" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "MV5BMTc0MzY2NjE0Nl5BMl5BanBnXkFtZTYwMDkxMDY0._V1_UY256_CR4,0,172,256_AL_", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 0, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 62, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "70B94A2C-C684-4AB5-AFE5-4CA194D59039", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/8c99aefa573b3ac7a325743d62ee07308c001cff.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "76450906-7605-4044-98C4-899A8702E351", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/C1AA2B99-E400-4E44-9000-E19A547ED3B9.png" + }, + { + "pbdfType": "symbol_master", + "id": "c756078b-9e00-45cf-8978-050e04f39e68", + "name": "person/frame", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person/frame", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 0.6509803922, + "green": 0.5764705882, + "red": 0.5333333333 + }, + "hasBackgroundColor": true, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": false, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 1230, + "y": 423 + }, + "id": "C756078B-9E00-45CF-8978-050E04F39E68", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E7CB6903-D45C-441E-9543-A5C17A761A67", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Oval", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": true, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "constraints": { + "scaleFactor": 1, + "model_version": 0.1, + "aspectRatio": { + "model_version": 0.1, + "enabled": 1, + "multiplier": 41, + "modelID": "constraint_64c14f23-c51a-4738-8138-7d8c1b67276e", + "model_class": "ADModelConstraint", + "constant": 41 + }, + "modelID": "viewConstraints_0101f9cb-7927-444d-9e59-4bd5d783a3f7", + "model_class": "ADModelViewConstraints", + "automatic": 1 + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614237490000004, 1}", + "curveMode": 2, + "curveTo": "{0.22385762510000001, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385762510000001}", + "curveMode": 2, + "curveTo": "{1, 0.77614237490000004}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22385762510000001, 0}", + "curveMode": 2, + "curveTo": "{0.77614237490000004, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77614237490000004}", + "curveMode": 2, + "curveTo": "{0, 0.22385762510000001}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "33D3EB50-74A6-45C9-99F5-77F7FBD13585", + "type": "oval", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "294B039E-96F7-4D90-97C1-97F074B5EB5B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 5.857142857142858, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 2, + "thickness": 2 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.0616508152173913, + "blue": 0, + "green": 0, + "red": 0 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "oval" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/C756078B-9E00-45CF-8978-050E04F39E68.png" + }, + { + "pbdfType": "symbol_master", + "id": "277a3d19-a01b-4e11-8f57-7c6d9b49749c", + "name": "person/1", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person/1", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "530E093C-4A76-41F1-9482-08004D962CD5", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [ + { + "overrideName": "B02B6AD6-5AD3-42B8-8234-715FC6EADCC6_image", + "canOverride": true + } + ], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 1230, + "y": 564 + }, + "id": "277A3D19-A01B-4E11-8F57-7C6D9B49749C", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "F2BD420D-6954-4B73-B256-04983CEC5DBE", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Group 4 Copy 3", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "399739F3-65D1-4732-BEAA-ECAC4C0D7FA1", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "7E50370E-1A23-400B-85BA-89B01F07E317", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Oval", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": true, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614237490000004, 1}", + "curveMode": 2, + "curveTo": "{0.22385762510000001, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385762510000001}", + "curveMode": 2, + "curveTo": "{1, 0.77614237490000004}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22385762510000001, 0}", + "curveMode": 2, + "curveTo": "{0.77614237490000004, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77614237490000004}", + "curveMode": 2, + "curveTo": "{0, 0.22385762510000001}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "75DA22C0-6FCC-4829-979A-08983DF78209", + "type": "oval", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "6D42CFB1-2DDA-4B3A-BCA6-5BEAC0EEF880", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 5.857142857142858, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 0.5857142857142857 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "oval" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "bearded-men-face-hipster-character-vector-14648253", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 0, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 43, + "width": 29, + "x": 6, + "y": 2 + }, + "id": "B02B6AD6-5AD3-42B8-8234-715FC6EADCC6", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/c74946529ab658fcc8913a8b157de9a55e262ce4.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "E02D5A6E-08BE-4541-A7FB-0F467F736480", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 0.3796296296296297, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0.2125211148648649, + "contrast": 2.480996621621621, + "hue": 1.159855311402397, + "saturation": 1.438978040540541 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/277A3D19-A01B-4E11-8F57-7C6D9B49749C.png" + }, + { + "pbdfType": "symbol_master", + "id": "ac76fba2-f9ca-4dee-94ed-03918f4ce652", + "name": "person/5", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person/5", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "00121EBB-86F2-4C74-8A1D-074B52B33010", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [ + { + "overrideName": "388230FE-E1E6-4477-BE2B-11FE9FF128F4_image", + "canOverride": true + } + ], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 1230, + "y": 705 + }, + "id": "AC76FBA2-F9CA-4DEE-94ED-03918F4CE652", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "3275527D-FC53-4D07-A11A-65177A1F519C", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "Group 8", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "B0A671DA-E5C3-4CA1-8129-DF398438902A", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "467F0FEA-A4AB-4BD4-814B-647B24C60DEF", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Oval", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": true, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614237490000004, 1}", + "curveMode": 2, + "curveTo": "{0.22385762510000001, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385762510000001}", + "curveMode": 2, + "curveTo": "{1, 0.77614237490000004}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22385762510000001, 0}", + "curveMode": 2, + "curveTo": "{0.77614237490000004, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77614237490000004}", + "curveMode": 2, + "curveTo": "{0, 0.22385762510000001}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "FF9FDA24-0C64-402A-B9C3-0B922A3B6A04", + "type": "oval", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "87AFDB99-5BDD-4DD3-9D46-187EB372CE68", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 5.857142857142858, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 0.5857142857142857 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.0616508152173913, + "blue": 0, + "green": 0, + "red": 0 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "oval" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "mens-slicked-back-grey-hair", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 0, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 47, + "width": 47, + "x": -3, + "y": 0 + }, + "id": "388230FE-E1E6-4477-BE2B-11FE9FF128F4", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/673b50671b86db7b6d722350ca4e47ec7c5e5f52.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "FFE7EF38-DBD5-46F2-86C0-265C6EAC4D90", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 4, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/AC76FBA2-F9CA-4DEE-94ED-03918F4CE652.png" + }, + { + "pbdfType": "symbol_master", + "id": "14464801-56ae-4b2e-888b-b7c56bb513dc", + "name": "person/12", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person/12", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "292AFD52-31A6-40B2-B087-3C35E9191616", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [ + { + "overrideName": "92EE7045-3A4C-4166-9326-40BE5FA11EF7_image", + "canOverride": true + } + ], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 1230, + "y": 846 + }, + "id": "14464801-56AE-4B2E-888B-B7C56BB513DC", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "CD7C7831-B5CB-42C8-8761-6F5F0D8C3C75", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Group 7", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": { + "constraints": { + "scaleFactor": 1, + "model_version": 0.1, + "aspectRatio": { + "model_class": "ADModelConstraint", + "enabled": 1, + "multiplier": 41, + "constant": 41, + "model_version": 0.1, + "modelID": "constraint_436decaf-18f5-4cd1-baa0-f343c56826c7" + }, + "modelID": "viewConstraints_b50092e9-7d9c-49c8-8fae-95464d18dd5c", + "model_class": "ADModelViewConstraints", + "automatic": 1 + } + } + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "9A8DF34F-5EEC-4FCA-9514-89713859A478", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "415CF93C-9E50-4E13-A3AB-9271B491FFDD", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "Oval", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": true, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.77614237490000004, 1}", + "curveMode": 2, + "curveTo": "{0.22385762510000001, 1}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0.22385762510000001}", + "curveMode": 2, + "curveTo": "{1, 0.77614237490000004}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{1, 0.5}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0.22385762510000001, 0}", + "curveMode": 2, + "curveTo": "{0.77614237490000004, 0}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0.5, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0.77614237490000004}", + "curveMode": 2, + "curveTo": "{0, 0.22385762510000001}", + "hasCurveFrom": true, + "hasCurveTo": true, + "point": "{0, 0.5}" + } + ], + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "8A87A39C-6EB4-4443-A3A3-405212186435", + "type": "oval", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B4C606FA-FEEB-46E6-A0DD-A56AFFA4D328", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 5.857142857142858, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": false, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 0, + "thickness": 0.5857142857142857 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 0.0616508152173913, + "blue": 0, + "green": 0, + "red": 0 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "oval" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "images (2)", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "fillReplacesImage": false, + "intendedDPI": 0, + "clippingMask": "{{0, 0}, {1, 1}}", + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": true, + "height": 42, + "width": 63, + "x": -18, + "y": 0 + }, + "id": "92EE7045-3A4C-4166-9326-40BE5FA11EF7", + "image": { + "_class": "MSJSONFileReference", + "_ref_class": "MSImageData", + "_ref": "images/9a74d63a137c7d69f65ba54a0e0e71f27b9a080f.png" + }, + "type": "bitmap", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "360D4F38-39DE-45AE-902D-C7E25E3EF2D9", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "image" + } + ], + "pbdfType": "group" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/14464801-56AE-4B2E-888B-B7C56BB513DC.png" + }, + { + "pbdfType": "symbol_master", + "id": "2c9ab975-28fc-40c1-ad16-a32bba023e53", + "name": "person/withframe", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "person/withframe", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "1E69FEC0-85F8-42BA-A987-F973EC2F19A8", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [ + { + "overrideName": "A268549D-9BCF-41CE-B386-6FFC1C85817B_symbolID", + "canOverride": true + }, + { + "overrideName": "772F0483-EB30-4642-AA0D-D56765C12CB4_symbolID", + "canOverride": true + } + ], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 1230, + "y": 987 + }, + "id": "2C9AB975-28FC-40C1-AD16-A32BBA023E53", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "B9785886-AE99-4DF6-B282-86FA0DC4AE05", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 1, + "name": "person/5", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "00121EBB-86F2-4C74-8A1D-074B52B33010", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "A268549D-9BCF-41CE-B386-6FFC1C85817B", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "16963334-55FD-44FA-9D5D-97FBEB09D968", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + }, + { + "booleanOperation": 0, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "person/frame", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": { + "com.animaapp.stc-sketch-plugin": { + "kModelPropertiesKey": {} + } + }, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "CLASS_NAME": null, + "overrideValues": [], + "scale": 1, + "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", + "verticalSpacing": 0, + "horizontalSpacing": 0, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 41, + "width": 41, + "x": 0, + "y": 0 + }, + "id": "772F0483-EB30-4642-AA0D-D56765C12CB4", + "type": "symbolInstance", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "04DB914B-AC53-4083-8348-9EDD919A45C8", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": true, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "parameters": null, + "pbdfType": "symbol_instance" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/2C9AB975-28FC-40C1-AD16-A32BBA023E53.png" + }, + { + "pbdfType": "symbol_master", + "id": "d377e55e-2dc6-446a-ac51-4c913a2b5692", + "name": "someElement/green", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "someElement/green", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "720A6B85-4F0B-45A3-96E0-3E9F50E46030", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 802, + "width": 979, + "x": 1371, + "y": 0 + }, + "id": "D377E55E-2DC6-446A-AC51-4C913A2B5692", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "20B93881-5A3E-4CEA-9DD1-7361412A3768", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "someElement/green", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 802, + "width": 979, + "x": 0, + "y": 0 + }, + "id": "CDE1848E-3FE3-4E75-A093-6510D452900F", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "1AE10229-B3F3-4F91-A6A0-BB0423999D44", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Rectangle", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 0, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 802, + "width": 979, + "x": 0, + "y": 0 + }, + "id": "6B7732F9-92DE-424D-AC15-A7C2305FC1B5", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "8AECAF89-8D3A-4D9A-8A77-FE15AD111F0B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 1, + "red": 0.2818509615384617 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + } + ], + "pbdfType": "group" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/D377E55E-2DC6-446A-AC51-4C913A2B5692.png" + }, + { + "pbdfType": "symbol_master", + "id": "d5f9ba19-3b15-490c-b31b-24aa26d8b77b", + "name": "someElement/default", + "convert": true, + "type": "symbolMaster", + "designNode": { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "someElement/default", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": true, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": true, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "backgroundColor": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + }, + "hasBackgroundColor": false, + "horizontalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInExport": true, + "includeInCloudUpload": true, + "isFlowHome": false, + "resizesContent": false, + "verticalRulerData": { + "_class": "rulerData", + "base": 0, + "guides": [] + }, + "includeBackgroundColorInInstance": false, + "symbolID": "3156C515-06F6-428E-8A5B-CB8B85B1F7F4", + "changeIdentifier": null, + "allowsOverrides": true, + "overrideProperties": [], + "presetDictionary": {}, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 802, + "width": 979, + "x": 1371, + "y": 902 + }, + "id": "D5F9BA19-3B15-490C-B31B-24AA26D8B77B", + "type": "symbolMaster", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "D471BC9E-BD31-484D-9CCA-D46CD7156BDD", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 2, + "name": "someElement/default", + "nameIsFixed": true, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "hasClickThrough": false, + "groupLayout": { + "_class": "MSImmutableFreeformGroupLayout" + }, + "CLASS_NAME": null, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 802, + "width": 979, + "x": 0, + "y": 0 + }, + "id": "F0D33876-5FA6-4524-A801-2F7F02351BB5", + "_ref": null, + "type": "group", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "FDB1A576-529D-4291-AAA3-1089F6E4AAB5", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "children": [ + { + "booleanOperation": -1, + "exportOptions": { + "_class": "exportOptions", + "includedLayerIds": [], + "layerOptions": 0, + "shouldTrim": false, + "exportFormats": [] + }, + "flow": null, + "isFixedToViewport": false, + "isFlippedHorizontal": false, + "isFlippedVertical": false, + "isLocked": false, + "layerListExpandedType": 0, + "name": "Rectangle", + "nameIsFixed": false, + "resizingConstraint": 63, + "resizingType": 0, + "rotation": 0, + "sharedStyleID": null, + "shouldBreakMaskChain": false, + "hasClippingMask": false, + "clippingMaskMode": 0, + "userInfo": null, + "maintainScrollPosition": null, + "prototypeNodeUUID": null, + "edited": false, + "isClosed": true, + "pointRadiusBehaviour": 1, + "points": [ + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 0}", + "curveMode": 1, + "curveTo": "{0, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 0}", + "curveMode": 1, + "curveTo": "{1, 0}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 0}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{1, 1}", + "curveMode": 1, + "curveTo": "{1, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{1, 1}" + }, + { + "_class": "curvePoint", + "cornerRadius": 0, + "curveFrom": "{0, 1}", + "curveMode": 1, + "curveTo": "{0, 1}", + "hasCurveFrom": false, + "hasCurveTo": false, + "point": "{0, 1}" + } + ], + "CLASS_NAME": null, + "fixedRadius": 0, + "hasConvertedToNewRoundCorners": true, + "needsConvertionToNewRoundCorners": false, + "absoluteBoundingBox": { + "_class": "rect", + "constrainProportions": false, + "height": 802, + "width": 979, + "x": 0, + "y": 0 + }, + "id": "2709F189-5E1B-478A-B3BC-D85FDE80B12F", + "type": "rectangle", + "visible": true, + "style": { + "_class": "style", + "do_objectID": "19705913-413B-4EF3-A749-6BE4FEC71E5B", + "endMarkerType": 0, + "miterLimit": 10, + "startMarkerType": 0, + "windingRule": 1, + "blur": { + "_class": "blur", + "isEnabled": false, + "center": "{0.5, 0.5}", + "motionAngle": 0, + "radius": 10, + "saturation": 1, + "type": 0 + }, + "borderOptions": { + "_class": "borderOptions", + "isEnabled": true, + "dashPattern": [], + "lineCapStyle": 0, + "lineJoinStyle": 0 + }, + "borders": [ + { + "_class": "border", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.592, + "green": 0.592, + "red": 0.592 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "position": 1, + "thickness": 1 + } + ], + "colorControls": { + "_class": "colorControls", + "isEnabled": false, + "brightness": 0, + "contrast": 1, + "hue": 0, + "saturation": 1 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "fills": [ + { + "_class": "fill", + "isEnabled": true, + "fillType": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0.847, + "green": 0.847, + "red": 0.847 + }, + "contextSettings": { + "_class": "graphicsContextSettings", + "blendMode": 0, + "opacity": 1 + }, + "gradient": { + "_class": "gradient", + "elipseLength": 0, + "from": "{0.5, 0}", + "gradientType": 0, + "to": "{0.5, 1}", + "stops": [ + { + "_class": "gradientStop", + "position": 0, + "color": { + "_class": "color", + "alpha": 1, + "blue": 1, + "green": 1, + "red": 1 + } + }, + { + "_class": "gradientStop", + "position": 1, + "color": { + "_class": "color", + "alpha": 1, + "blue": 0, + "green": 0, + "red": 0 + } + } + ] + }, + "noiseIndex": 0, + "noiseIntensity": 0, + "patternFillType": 1, + "patternTileScale": 1 + } + ], + "innerShadows": null, + "shadows": null, + "textStyle": null + }, + "pbdfType": "rectangle" + } + ], + "pbdfType": "group" + } + ], + "parameters": null, + "pbdfType": "symbol_master" + }, + "azure_blob_uri": "/D5F9BA19-3B15-490C-B31B-24AA26D8B77B.png" + } + ] + } + ], + "miscPages": [ + { + "pbdfType": "design_page", + "id": "C056F644-E132-461B-84D6-9B3ABCACFD0C", + "name": "third_party_widgets", + "convert": true, + "screens": [] + } + ], + "azure_container_uri": "" +} \ No newline at end of file diff --git a/TESTJSON/temp.json b/TESTJSON/temp.json new file mode 100644 index 00000000..98c6894c --- /dev/null +++ b/TESTJSON/temp.json @@ -0,0 +1 @@ +{"projectName":"temp","pbdfType":"project","id":"5YVG9vFxbbmoFIhw2MxuIL","pages":[{"pbdfType":"design_page","id":"0:66","name":"Index Screens","convert":true,"screens":[{"pbdfType":"screen","id":"0:67","name":"Majors Overview","convert":true,"type":null,"designNode":{"id":"0:67","name":"Majors Overview","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":812.0,"width":375.0,"x":690.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:68","name":"header","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":690.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:69","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":690.0,"y":-295.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","visible":false,"type":"GRADIENT_LINEAR","gradientHandlePositions":[{"x":1.5,"y":0.5},{"x":0.5,"y":-0.5},{"x":2.0,"y":0.0}],"gradientStops":[{"color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0},"position":0.0},{"color":{"r":0.21176470816135406,"g":0.33725491166114807,"b":0.7647058963775635,"a":1.0},"position":1.0}]},{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:70","name":"userScore","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":70.0,"x":844.0,"y":-244.0},"transitionNodeID":null,"children":[{"id":"0:71","name":"285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":27.0,"width":38.0,"x":844.0,"y":-244.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:72","name":"starIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":22.0,"x":892.0,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"561adcc26e02e562330294d1ef7cb73d7d78b1b5","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:73","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":30.0,"width":25.161291122436523,"x":707.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fc4b89babe0fe59e003d8203615ac3d519f96daa","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:74","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":34.0,"width":34.0,"x":1016.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:75","name":"Recommended Majors","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":179.0,"x":707.0,"y":-6.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Recommended Majors","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:76","name":"Favorites","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":74.0,"x":707.0,"y":-129.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Favorites","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:77","name":"SmallMajorCard","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":-96.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:77;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":-96.0},"transitionNodeID":null,"children":[{"id":"I0:77;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":-96.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:77;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":719.0,"y":-83.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:77;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":-88.0},"transitionNodeID":null,"children":[{"id":"I0:77;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":-88.0},"transitionNodeID":null,"children":[{"id":"I0:77;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":-88.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:77;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":839.0,"y":-82.0},"transitionNodeID":null,"children":[{"id":"I0:77;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":840.6666870117188,"y":-79.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:78","name":"SmallMajorCard Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":-96.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:78;0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":-96.0},"transitionNodeID":null,"children":[{"id":"I0:78;0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":-96.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:78;0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":897.0,"y":-83.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:78;41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":-88.0},"transitionNodeID":null,"children":[{"id":"I0:78;41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":-88.0},"transitionNodeID":null,"children":[{"id":"I0:78;41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":-88.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:78;41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1017.0,"y":-82.0},"transitionNodeID":null,"children":[{"id":"I0:78;41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1018.6666870117188,"y":-79.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:56","pbdfType":null},{"id":"0:79","name":"1. Bars / 2. Top Bar / 2. Large / Heading + Search","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":113.0,"x":705.0,"y":-182.0},"transitionNodeID":null,"children":[{"id":"0:80","name":"🅰️ Heading","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":104.0,"x":705.0,"y":-182.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.014475814066827297,"g":0.1713331937789917,"b":0.36188071966171265,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Majors","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:81","name":"SmallMajorCard","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":31.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:81;0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":31.0},"transitionNodeID":null,"children":[{"id":"I0:81;0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":31.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:81;0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":718.0,"y":44.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:81;41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":39.0},"transitionNodeID":null,"children":[{"id":"I0:81;41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":39.0},"transitionNodeID":null,"children":[{"id":"I0:81;41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":39.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:81;41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":838.0,"y":45.0},"transitionNodeID":null,"children":[{"id":"I0:81;41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":839.6666870117188,"y":47.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:56","pbdfType":null},{"id":"0:82","name":"SmallMajorCard Copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":124.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:82;0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"I0:82;0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":124.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:82;0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":718.0,"y":137.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:82;41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":132.0},"transitionNodeID":null,"children":[{"id":"I0:82;41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":132.0},"transitionNodeID":null,"children":[{"id":"I0:82;41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":132.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:82;41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":838.0,"y":138.0},"transitionNodeID":null,"children":[{"id":"I0:82;41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":839.6666870117188,"y":140.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:56","pbdfType":null},{"id":"0:83","name":"SmallMajorCard Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":124.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:83;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"I0:83;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":124.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:83;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":896.0,"y":137.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:83;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":132.0},"transitionNodeID":null,"children":[{"id":"I0:83;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":132.0},"transitionNodeID":null,"children":[{"id":"I0:83;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":132.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:83;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1016.0,"y":138.0},"transitionNodeID":null,"children":[{"id":"I0:83;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1017.6666870117188,"y":140.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:84","name":"SmallMajorCard Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":31.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:84;0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":31.0},"transitionNodeID":null,"children":[{"id":"I0:84;0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":31.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:84;0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":896.0,"y":44.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:84;41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":39.0},"transitionNodeID":null,"children":[{"id":"I0:84;41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":39.0},"transitionNodeID":null,"children":[{"id":"I0:84;41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":39.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:84;41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1016.0,"y":45.0},"transitionNodeID":null,"children":[{"id":"I0:84;41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1017.6666870117188,"y":47.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:56","pbdfType":null},{"id":"0:85","name":"Most Popular Majors","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":167.0,"x":707.0,"y":221.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Most Popular Majors","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:86","name":"SmallMajorCard","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":254.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:86;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":254.0},"transitionNodeID":null,"children":[{"id":"I0:86;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":254.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:86;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":718.0,"y":267.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:86;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":262.0},"transitionNodeID":null,"children":[{"id":"I0:86;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":262.0},"transitionNodeID":null,"children":[{"id":"I0:86;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":262.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:86;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":838.0,"y":268.0},"transitionNodeID":null,"children":[{"id":"I0:86;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":839.6666870117188,"y":270.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:87","name":"SmallMajorCard Copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":347.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:87;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":347.0},"transitionNodeID":null,"children":[{"id":"I0:87;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":347.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:87;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":719.0,"y":360.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:87;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":355.0},"transitionNodeID":null,"children":[{"id":"I0:87;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":355.0},"transitionNodeID":null,"children":[{"id":"I0:87;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":355.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:87;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":839.0,"y":361.0},"transitionNodeID":null,"children":[{"id":"I0:87;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":840.6666870117188,"y":363.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:88","name":"SmallMajorCard Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":347.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:88;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":347.0},"transitionNodeID":null,"children":[{"id":"I0:88;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":347.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:88;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":897.0,"y":360.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:88;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":355.0},"transitionNodeID":null,"children":[{"id":"I0:88;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":355.0},"transitionNodeID":null,"children":[{"id":"I0:88;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":355.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:88;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1017.0,"y":361.0},"transitionNodeID":null,"children":[{"id":"I0:88;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1018.6666870117188,"y":363.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:89","name":"SmallMajorCard Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":254.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:89;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":254.0},"transitionNodeID":null,"children":[{"id":"I0:89;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":254.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:89;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":896.0,"y":267.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:89;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":262.0},"transitionNodeID":null,"children":[{"id":"I0:89;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":262.0},"transitionNodeID":null,"children":[{"id":"I0:89;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":262.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:89;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1016.0,"y":268.0},"transitionNodeID":null,"children":[{"id":"I0:89;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1017.6666870117188,"y":270.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:90","name":"Advanced Search","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.0,"width":119.0,"x":931.0,"y":-168.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.5568627715110779,"b":0.9490196108818054,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Advanced Search","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9490196108818054,"g":0.5568627715110779,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.9490196108818054,"g":0.5568627715110779,"r":0.21176470816135406},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:91","name":"normal","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":56.0,"width":302.0,"x":730.0,"y":439.0},"transitionNodeID":null,"children":[{"id":"0:95","name":"2homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":26.0,"x":730.0,"y":455.86328125},"transitionNodeID":"0:172","children":[{"id":"0:92","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":26.0,"x":730.0,"y":455.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:93","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":26.0,"x":730.0,"y":455.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:94","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.729411780834198,"g":0.6235294342041016,"r":0.5843137502670288},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":26.0,"x":730.0,"y":455.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5843137502670288,"g":0.6235294342041016,"b":0.729411780834198,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:96","name":"stats","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:119","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":938.0,"y":458.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"726d1978755b145b9ac3fd39d36552d1cec12b72","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:97","name":"plus-icon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":56.0,"width":50.90909194946289,"x":852.0,"y":439.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"05cf0e11c179692ec2fcb5eff64e817a9596d400","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:98","name":"not published","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":23.33333396911621,"width":23.33333396911621,"x":799.0,"y":457.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1bee5266944df41f0f6cd87832566d650163ddfe","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:99","name":"learn","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:214","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":21.0,"width":24.0,"x":1008.0,"y":462.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"b12d692ccfdf45980c55fc36de927c9ac37f466b","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:67.png"},{"pbdfType":"screen","id":"0:100","name":"Landing Page","convert":true,"type":null,"designNode":{"id":"0:100","name":"Landing Page","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":812.0,"width":375.0,"x":2154.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:101","name":"iPhone X Blue@3x","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":413.0,"width":221.0,"x":2232.0,"y":-189.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"acb2bef09f1e01f874c772febcb4ececdc2ab52d","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:102","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":271.0,"width":375.0,"x":2154.0,"y":246.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:103","name":"A new way to learn a","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":292.0,"x":2195.0,"y":268.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.014475814066827297,"g":0.1713331937789917,"b":0.36188071966171265,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"A new way to learn about careers","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:104","name":"Inspyred provides re","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":235.0,"x":2224.0,"y":297.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.46666666865348816,"g":0.5254902243614197,"b":0.6196078658103943,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Inspyred provides resources to help you make the best decisions.","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.6196078658103943,"g":0.5254902243614197,"r":0.46666666865348816},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.6196078658103943,"g":0.5254902243614197,"r":0.46666666865348816},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:105","name":"Main-button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2198.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:106","name":"Create Account","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2198.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:107","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2198.0,"y":369.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":100.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:108","name":"Sign Up","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":66.0,"x":2309.0,"y":381.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Sign Up","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:109","name":"Create Account","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2195.0,"y":430.0},"transitionNodeID":"0:172","children":[{"id":"0:110","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":1.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2195.0,"y":430.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":100.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:111","name":"Log in","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":55.0,"x":2311.5,"y":442.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.4921875,"g":0.4921875,"b":0.4921875,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Log in","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.4921875,"g":0.4921875,"r":0.4921875},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.4921875,"g":0.4921875,"r":0.4921875},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:112","name":"header","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":2154.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:113","name":"background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":2154.0,"y":-295.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","visible":false,"type":"GRADIENT_LINEAR","gradientHandlePositions":[{"x":1.5,"y":0.5},{"x":0.5,"y":-0.5},{"x":2.0,"y":0.0}],"gradientStops":[{"color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0},"position":0.0},{"color":{"r":0.21176470816135406,"g":0.33725491166114807,"b":0.7647058963775635,"a":1.0},"position":1.0}]},{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:114","name":"userScore","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":70.0,"x":2307.0,"y":-244.0},"transitionNodeID":null,"children":[{"id":"0:115","name":"285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":27.0,"width":40.0,"x":2307.0,"y":-244.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:116","name":"starIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":22.0,"x":2355.0,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"561adcc26e02e562330294d1ef7cb73d7d78b1b5","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:117","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":30.0,"width":25.0,"x":2171.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fc4b89babe0fe59e003d8203615ac3d519f96daa","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:118","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":34.0,"width":34.0,"x":2480.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:100.png"},{"pbdfType":"screen","id":"0:119","name":"Community Groups","convert":true,"type":null,"designNode":{"id":"0:119","name":"Community Groups","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":812.0,"width":375.0,"x":1679.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:120","name":"header","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":1679.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:121","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":1679.0,"y":-295.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:122","name":"userScore","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":70.0,"x":1832.0,"y":-244.0},"transitionNodeID":null,"children":[{"id":"0:123","name":"285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":27.0,"width":38.0,"x":1832.0,"y":-244.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:124","name":"starIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":22.0,"x":1880.0,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"561adcc26e02e562330294d1ef7cb73d7d78b1b5","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:125","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":29.225807189941406,"width":25.161291122436523,"x":1696.0,"y":-246.22579956054688},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"70d7696e0256bf5b87fe826a9142b64539ece51a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:126","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":34.0,"width":34.0,"x":2005.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:127","name":"Your Groups","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":101.0,"x":1696.0,"y":-184.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Your Groups","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:128","name":"More Groups","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":105.0,"x":1696.0,"y":4.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"More Groups","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:129","name":"Cell1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":124.0,"width":245.0,"x":1696.0,"y":-147.0},"transitionNodeID":null,"children":[{"id":"0:130","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":1.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":124.0,"width":245.0,"x":1696.0,"y":-147.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"INSIDE","styles":null,"fills":[],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:131","name":"High School Group","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":155.0,"x":1710.0,"y":-134.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"High School Group","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:132","name":"People Group 1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":89.0,"x":1710.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:18","name":"person 9","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1710.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:19","name":"Group 8","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1710.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:20","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1710.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"29:21","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1710.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"29:22","name":"mens-slicked-back-grey-hair","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":47.0,"width":47.0,"x":1707.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"466b9d7e969ee5eae4fa60480890a3c382b99131","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"29:9","name":"person 9","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:10","name":"person/1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I29:10;0:29","name":"Group 4 Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I29:10;0:30","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I29:10;0:32","name":"bearded-men-face-hipster-character-vector-14648253","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":43.0,"width":29.0,"x":1740.0,"y":-77.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fa88d58c5f0e4e19ea1f1da0bc095f753c04260c","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:28","pbdfType":null},{"id":"79:111","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:112","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:113","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"29:0","name":"person 9 copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:1","name":"person/12","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I29:1;0:39","name":"Group 7","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I29:1;0:40","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I29:1;0:42","name":"images (2)","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":63.0,"x":1740.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"762e6bf5275df04d86809d5558393e736b689df2","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:38","pbdfType":null},{"id":"79:108","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:109","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:110","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:136","name":"Cell2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":124.0,"width":245.0,"x":1953.0,"y":-147.0},"transitionNodeID":null,"children":[{"id":"0:137","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":1.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":124.0,"width":245.0,"x":1953.0,"y":-147.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"INSIDE","styles":null,"fills":[],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:138","name":"Programming","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":112.0,"x":1979.0,"y":-134.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Programming","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:139","name":"People Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":89.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"0:140","name":"person 9 copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"0:141","name":"person/5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:141;0:21","name":"Group 7","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I0:141;0:22","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:141;0:24","name":"MV5BMTc0MzY2NjE0Nl5BMl5BanBnXkFtZTYwMDkxMDY0._V1_UY256_CR4,0,172,256_AL_","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":62.0,"width":41.0,"x":1979.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"da827996130fb49beae52d638023a3c521add634","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:20","pbdfType":null},{"id":"79:120","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:121","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:122","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:143","name":"person 9 copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"0:144","name":"person/5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:144;0:11","name":"Group 11","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I0:144;0:12","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:144;0:14","name":"MV5BMjAwMzc5OTEzOF5BMl5BanBnXkFtZTgwMDc5ODU3MTE@._V1_UX172_CR0,0,172,256_AL_","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":41.0,"x":2003.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"d3bd9ca71b3fe97e05ddf694a700390c236d4c38","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:10","pbdfType":null},{"id":"79:117","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:118","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:119","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:146","name":"person 9 copy 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"0:147","name":"person/5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:147;0:16","name":"Group 9 Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I0:147;0:17","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:147;0:19","name":"download","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":42.0,"x":2026.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"0ee38c205bd2ebee137b0ff0ba528cf791c37df6","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:15","pbdfType":null},{"id":"79:114","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:115","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:116","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:149","name":"groups","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":344.0,"width":358.0,"x":1696.0,"y":77.0},"transitionNodeID":null,"children":[{"id":"0:150","name":"Algorithms","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":92.0,"x":1696.0,"y":77.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Algorithms","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:151","name":"Nursing","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":65.0,"x":1696.0,"y":142.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Nursing","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:152","name":"Dog Photos","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":94.0,"x":1696.0,"y":207.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Dog Photos","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:153","name":"Sports","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":54.0,"x":1696.0,"y":272.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Sports","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:154","name":"Band","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":42.0,"x":1696.0,"y":336.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Band","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:155","name":"Party time","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":86.0,"x":1696.0,"y":401.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Party time","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:156","name":"Line Copy","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":117.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:157","name":"Line Copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":182.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:158","name":"Line Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":247.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:159","name":"Line Copy 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":312.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:160","name":"Line Copy 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":376.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:161","name":"Line","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":1.0,"width":187.5,"x":1679.0,"y":42.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.5176470875740051,"b":1.0,"a":1.0}}],"strokeWeight":3.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:162","name":"normal","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":56.0,"width":302.0,"x":1719.0,"y":434.0},"transitionNodeID":null,"children":[{"id":"0:166","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":25.739999771118164,"x":1719.0,"y":450.86328125},"transitionNodeID":"0:172","children":[{"id":"0:163","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":25.739999771118164,"x":1719.0,"y":450.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:164","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":25.739999771118164,"x":1719.0,"y":450.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:165","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.729411780834198,"g":0.6235294342041016,"r":0.5843137502670288},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":25.739999771118164,"x":1719.0,"y":450.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5843137502670288,"g":0.6235294342041016,"b":0.729411780834198,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:167","name":"stats","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1927.0,"y":453.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"726d1978755b145b9ac3fd39d36552d1cec12b72","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:168","name":"plus-icon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":56.0,"width":50.90909194946289,"x":1841.0,"y":434.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"05cf0e11c179692ec2fcb5eff64e817a9596d400","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:169","name":"not published","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:67","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":23.33333396911621,"width":23.33333396911621,"x":1788.0,"y":452.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1bee5266944df41f0f6cd87832566d650163ddfe","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:170","name":"learn","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:214","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":21.0,"width":24.0,"x":1997.0,"y":457.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"b12d692ccfdf45980c55fc36de927c9ac37f466b","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:171","name":"Create New","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.0,"width":76.0,"x":1946.0,"y":-181.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.48235294222831726,"b":0.886274516582489,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Create New","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.886274516582489,"g":0.48235294222831726,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.886274516582489,"g":0.48235294222831726,"r":0.2078431397676468},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:119.png"},{"pbdfType":"screen","id":"0:172","name":"HomeScreenAlt","convert":true,"type":null,"designNode":{"id":"0:172","name":"HomeScreenAlt","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":896.0,"width":414.0,"x":1165.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:173","name":"Top Stack Section","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":610.0,"width":414.0,"x":1165.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:174","name":"backgroundImage","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":529.0,"width":414.0,"x":1165.0,"y":-295.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"65337f67361e93ec60270000b045aa826d92a5d8","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:175","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":258.0,"x":1244.0,"y":-164.0},"transitionNodeID":null,"children":[{"id":"0:176","name":"Noam Levine","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":115.76923370361328,"x":1314.5640869140625,"y":-163.5238037109375},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Noam Levine","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:177","name":"Student at Hanks Hig","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":256.8974304199219,"x":1244.55126953125,"y":-140.4761962890625},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Student at Hanks High School","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:178","name":"Completion Graph","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":88.0,"width":131.0,"x":1307.0,"y":-10.0},"transitionNodeID":null,"children":[{"id":"2:135","name":"Component 1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":87.32353210449219,"width":131.0,"x":1307.0,"y":-9.882352828979492},"transitionNodeID":null,"children":[{"id":"0:179","name":"72%","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":77.0,"width":131.0,"x":1307.0,"y":-9.882352828979492},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"72%","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:180","name":"Completed","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":91.3697509765625,"x":1326.815185546875,"y":58.44117736816406},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.800000011920929,"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Completed","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:181","name":"ScoreCard","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":128.0,"width":414.0,"x":1165.0,"y":187.0},"transitionNodeID":null,"children":[{"id":"0:182","name":"Score Bar@3x","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":128.0,"width":414.0,"x":1165.0,"y":187.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"ea2cf7390a161fe48fcd63570a39acf952b1eb54","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:183","name":"Score: 285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":28.0,"width":125.85600280761719,"x":1309.072021484375,"y":227.95040893554688},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21548150479793549,"g":0.19963327050209045,"b":0.19963327050209045,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Score: 285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.19963327050209045,"g":0.19963327050209045,"r":0.21548150479793549},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.19963327050209045,"g":0.19963327050209045,"r":0.21548150479793549},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[4.0,4.0,4.0,4.0,4.0,4.0,4.0,3.0,3.0,3.0],"styleOverrideTable":{"4":{"fontFamily":"Sanchez","fontPostScriptName":"Sanchez-Regular","fontWeight":400},"3":{"fontFamily":"Sanchez","fontPostScriptName":"Sanchez-Regular","fontWeight":400,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5372549295425415,"b":0.9333333373069763,"a":1.0}}]}},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:184","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":36.0,"width":38.0,"x":1522.0,"y":-245.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:185","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":30.0,"width":28.0,"x":1184.0,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"70d7696e0256bf5b87fe826a9142b64539ece51a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:186","name":"Connect Facebook Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":315.0},"transitionNodeID":null,"children":[{"id":"0:187","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":315.0},"transitionNodeID":null,"children":[{"id":"0:189","name":"Rectangle 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":315.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}},{"opacity":0.5,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.25882354378700256,"g":0.40392157435417175,"b":0.6980392336845398,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":30.5,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:188","name":"Rectangle 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":315.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}},{"opacity":0.5,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.25882354378700256,"g":0.40392157435417175,"b":0.6980392336845398,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":30.5,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:190","name":"Continue","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":190.0,"x":1289.0,"y":336.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Connect facebook","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:191","name":"Page 1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":61.0,"x":1201.0,"y":315.0},"transitionNodeID":null,"children":[{"id":"0:192","name":"Oval 5","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":61.0,"x":1201.0,"y":315.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.25882354378700256,"g":0.40392157435417175,"b":0.6980392336845398,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:193","name":"Fill 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":47.0,"width":25.0,"x":1225.0,"y":329.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:194","name":"Invite Friends Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":404.0},"transitionNodeID":null,"children":[{"id":"0:195","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":404.0},"transitionNodeID":null,"children":[{"id":"0:197","name":"Rectangle 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":404.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}},{"opacity":0.44999998807907104,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0941176488995552,"g":0.7882353067398071,"b":0.8901960849761963,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":30.5,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:196","name":"Rectangle 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":404.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}},{"opacity":0.44999998807907104,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0941176488995552,"g":0.7882353067398071,"b":0.8901960849761963,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":30.5,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:198","name":"Invite Friends","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":146.0,"x":1289.0,"y":425.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Invite Friends","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:199","name":"Spotify Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":61.0,"x":1201.0,"y":404.0},"transitionNodeID":null,"children":[{"id":"0:200","name":"Spotify","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":61.0,"x":1201.0,"y":404.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0941176488995552,"g":0.7882353067398071,"b":0.8901960849761963,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:201","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":29.0,"width":44.0,"x":1210.0,"y":421.0},"transitionNodeID":null,"children":[{"id":"0:202","name":"Fill 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.0,"width":44.0,"x":1210.0,"y":421.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:203","name":"Fill 6","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":14.0,"width":26.0,"x":1219.0,"y":436.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:204","name":"person","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":82.0,"width":85.0,"x":1331.0,"y":-251.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"62b79ea6babc1f4ab6b7b3ffde1833016d810a9d","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:205","name":"normal","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":322.0,"x":1211.0,"y":521.0},"transitionNodeID":null,"children":[{"id":"0:209","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":27.719999313354492,"x":1211.0,"y":540.0},"transitionNodeID":null,"children":[{"id":"0:206","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":27.719999313354492,"x":1211.0,"y":540.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:207","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":27.719999313354492,"x":1211.0,"y":540.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:208","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.729411780834198,"g":0.6235294342041016,"r":0.5843137502670288},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":27.719999313354492,"x":1211.0,"y":540.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5843137502670288,"g":0.6235294342041016,"b":0.729411780834198,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:210","name":"stats","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:119","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":26.0,"x":1433.0,"y":542.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"726d1978755b145b9ac3fd39d36552d1cec12b72","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:211","name":"plus-icon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":54.0,"x":1341.0,"y":521.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"05cf0e11c179692ec2fcb5eff64e817a9596d400","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:212","name":"not published","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:67","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":25.0,"x":1285.0,"y":541.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1bee5266944df41f0f6cd87832566d650163ddfe","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:213","name":"learn","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:214","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":23.0,"width":26.0,"x":1507.0,"y":546.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"b12d692ccfdf45980c55fc36de927c9ac37f466b","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:172.png"},{"pbdfType":"screen","id":"0:214","name":"LearningOverviewAlt","convert":true,"type":null,"designNode":{"id":"0:214","name":"LearningOverviewAlt","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":896.0,"width":414.0,"x":176.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:215","name":"header","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":414.0,"x":176.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:216","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":414.0,"x":176.0,"y":-295.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:217","name":"userScore","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":78.0,"x":344.9119873046875,"y":-244.0},"transitionNodeID":null,"children":[{"id":"0:218","name":"285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":27.0,"width":38.0,"x":344.9119873046875,"y":-244.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:219","name":"starIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":24.288000106811523,"x":397.90399169921875,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"561adcc26e02e562330294d1ef7cb73d7d78b1b5","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:220","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":29.225807189941406,"width":27.778064727783203,"x":194.76800537109375,"y":-246.22579956054688},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"70d7696e0256bf5b87fe826a9142b64539ece51a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:221","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":34.0,"width":37.5359992980957,"x":535.9039916992188,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:222","name":"Categories","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":87.0,"x":199.0,"y":-135.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Categories","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:223","name":"1. Bars / 2. Top Bar / 2. Large / Heading + Search","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":126.0,"x":198.0,"y":-182.0},"transitionNodeID":null,"children":[{"id":"0:224","name":"🅰️ Heading","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":120.0,"x":198.0,"y":-182.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.014475814066827297,"g":0.1713331937789917,"b":0.36188071966171265,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Explore","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:225","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":198.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:226","name":"Group","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":198.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:227","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":198.0,"y":-97.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:228","name":"Careers","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":63.0,"x":220.0,"y":32.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Careers","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:229","name":"simplePaperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":74.0,"width":73.0,"x":214.0,"y":-69.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"2ce8b7c0c797b888993f960fa5e1accfb130705a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:230","name":"Group 2 Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":331.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:231","name":"Group","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":331.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:232","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":331.0,"y":-97.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:233","name":"Majors","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":54.0,"x":357.0,"y":32.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Majors","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:234","name":"simplePaperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":74.0,"width":73.0,"x":347.0,"y":-69.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"2ce8b7c0c797b888993f960fa5e1accfb130705a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:235","name":"Group 2 Copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":464.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:236","name":"Group","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":464.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:237","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":464.0,"y":-97.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:238","name":"Colleges","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":69.0,"x":482.0,"y":32.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Colleges","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:239","name":"simplePaperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":74.0,"width":73.0,"x":480.0,"y":-69.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"2ce8b7c0c797b888993f960fa5e1accfb130705a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:240","name":"Continue Learning","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":152.0,"x":199.0,"y":76.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Continue Learning","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:241","name":"View All","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.0,"width":58.0,"x":516.0,"y":80.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.5568627715110779,"b":0.9490196108818054,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"View All","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9490196108818054,"g":0.5568627715110779,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.9490196108818054,"g":0.5568627715110779,"r":0.21176470816135406},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:242","name":"Lesson Big Card","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:243","name":"Group 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:244","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.772549033164978,"g":0.21176470816135406,"r":0.49803921580314636},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":124.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.49803921580314636,"g":0.21176470816135406,"b":0.772549033164978,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:245","name":"Fundamentals of Algo","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":115.0,"x":232.5,"y":138.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Fundamentals\nof Algorithms","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:246","name":"paperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":97.0,"width":97.0,"x":241.0,"y":198.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fc1e80e0188ea1eef90949eba199e5d82cc36845","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:247","name":"Group 5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:248","name":"Lesson Big Card Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:249","name":"Group 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:250","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.0,"g":0.0,"r":0.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":124.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.8500000238418579,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:251","name":"Finance","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":65.0,"x":444.0,"y":138.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Finance","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:252","name":"cashIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":93.0,"width":132.0,"x":410.0,"y":198.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"5afc3234c772299d4b12566e8f0b8229ec78c5d8","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:253","name":"Lessons","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":66.0,"x":212.0,"y":331.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Lessons","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:254","name":"Lesson Big Card","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:255","name":"Group 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:256","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.772549033164978,"g":0.21176470816135406,"r":0.49803921580314636},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":369.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.49803921580314636,"g":0.21176470816135406,"b":0.772549033164978,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:257","name":"Fundamentals of Algo","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":115.0,"x":232.5,"y":383.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Fundamentals\nof Algorithms","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:258","name":"paperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":97.0,"width":97.0,"x":241.0,"y":443.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fc1e80e0188ea1eef90949eba199e5d82cc36845","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:259","name":"Group 5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:260","name":"Lesson Big Card Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:261","name":"Group 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:262","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.0,"g":0.0,"r":0.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":369.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.8500000238418579,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:263","name":"Finance","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":65.0,"x":444.0,"y":383.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Finance","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:264","name":"cashIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":93.0,"width":132.0,"x":410.0,"y":443.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"5afc3234c772299d4b12566e8f0b8229ec78c5d8","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:265","name":"normal","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":59.890907287597656,"width":322.0,"x":223.0,"y":523.7393798828125},"transitionNodeID":null,"children":[{"id":"0:269","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":28.0,"x":223.0,"y":542.0},"transitionNodeID":"0:172","children":[{"id":"0:266","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":28.0,"x":223.0,"y":542.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:267","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":28.0,"x":223.0,"y":542.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:268","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.729411780834198,"g":0.6235294342041016,"r":0.5843137502670288},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":28.0,"x":223.0,"y":542.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5843137502670288,"g":0.6235294342041016,"b":0.729411780834198,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:270","name":"stats","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:119","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":26.0,"x":445.0,"y":544.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"726d1978755b145b9ac3fd39d36552d1cec12b72","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:271","name":"plus-icon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":59.890907287597656,"width":52.560001373291016,"x":353.7200012207031,"y":523.7393798828125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"2820aa24bc5fef31f345f96b4c97f6337cef54c3","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:272","name":"not published","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:67","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":25.0,"x":297.0,"y":545.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1bee5266944df41f0f6cd87832566d650163ddfe","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:273","name":"learn","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":23.0,"width":26.0,"x":519.0,"y":548.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"b12d692ccfdf45980c55fc36de927c9ac37f466b","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:214.png"}]},{"pbdfType":"design_page","id":"0:1","name":"Symbols","convert":true,"screens":[{"pbdfType":"screen","id":"0:61","name":"SmallMajorCard/loved","convert":true,"type":null,"designNode":{"id":"0:61","name":"SmallMajorCard/loved","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":148.0},"transitionNodeID":null,"children":[{"id":"0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":148.0},"transitionNodeID":null,"children":[{"id":"0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":148.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":1383.0,"y":161.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":156.0},"transitionNodeID":null,"children":[{"id":"41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":156.0},"transitionNodeID":null,"children":[{"id":"41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":156.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1503.0,"y":162.0},"transitionNodeID":null,"children":[{"id":"41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1504.6666259765625,"y":164.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:61.png"},{"pbdfType":"screen","id":"0:56","name":"SmallMajorCard/default","convert":true,"type":null,"designNode":{"id":"0:56","name":"SmallMajorCard/default","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":-28.0},"transitionNodeID":null,"children":[{"id":"0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":-28.0},"transitionNodeID":null,"children":[{"id":"0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":-28.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":1383.0,"y":-15.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":-20.0},"transitionNodeID":null,"children":[{"id":"41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":-20.0},"transitionNodeID":null,"children":[{"id":"41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":-20.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1503.0,"y":-14.0},"transitionNodeID":null,"children":[{"id":"41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1504.6666259765625,"y":-11.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:56.png"},{"pbdfType":"screen","id":"0:54","name":"Icons / Love","convert":true,"type":null,"designNode":{"id":"0:54","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1371.0,"y":248.0},"transitionNodeID":null,"children":[{"id":"0:55","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.350000381469727,"width":20.0,"x":1373.0,"y":251.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:54.png"},{"pbdfType":"screen","id":"0:52","name":"Icons / Love","convert":true,"type":null,"designNode":{"id":"0:52","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1371.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:53","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.350000381469727,"width":20.0,"x":1373.0,"y":127.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:52.png"},{"pbdfType":"screen","id":"0:48","name":"Buttons / Round / 2. Secondary / 32px","convert":true,"type":null,"designNode":{"id":"0:48","name":"Buttons / Round / 2. Secondary / 32px","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":100.0,"y":396.0},"transitionNodeID":null,"children":[{"id":"0:49","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":100.0,"y":396.0},"transitionNodeID":null,"children":[{"id":"0:50","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":100.0,"y":396.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:51","name":"🧡 Icon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":106.0,"y":402.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:51;0:47","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":106.0,"y":402.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.6705729365348816,"g":0.6705729365348816,"b":0.6705729365348816,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"componentId":"0:46","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:48.png"},{"pbdfType":"screen","id":"0:46","name":"Icons / Icon Area","convert":true,"type":null,"designNode":{"id":"0:46","name":"Icons / Icon Area","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1371.0,"y":-72.0},"transitionNodeID":null,"children":[{"id":"0:47","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1371.0,"y":-72.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.6705729365348816,"g":0.6705729365348816,"b":0.6705729365348816,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:46.png"},{"pbdfType":"screen","id":"0:38","name":"person/12","convert":true,"type":null,"designNode":{"id":"0:38","name":"person/12","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":846.0},"transitionNodeID":null,"children":[{"id":"0:39","name":"Group 7","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":846.0},"transitionNodeID":null,"children":[{"id":"0:40","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":846.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:42","name":"images (2)","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":63.0,"x":1212.0,"y":846.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"762e6bf5275df04d86809d5558393e736b689df2","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:38.png"},{"pbdfType":"screen","id":"0:33","name":"person/5","convert":true,"type":null,"designNode":{"id":"0:33","name":"person/5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":705.0},"transitionNodeID":null,"children":[{"id":"0:34","name":"Group 8","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":705.0},"transitionNodeID":null,"children":[{"id":"0:35","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":705.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:37","name":"mens-slicked-back-grey-hair","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":47.0,"width":47.0,"x":1227.0,"y":705.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"466b9d7e969ee5eae4fa60480890a3c382b99131","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:33.png"},{"pbdfType":"screen","id":"0:28","name":"person/1","convert":true,"type":null,"designNode":{"id":"0:28","name":"person/1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":564.0},"transitionNodeID":null,"children":[{"id":"0:29","name":"Group 4 Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":564.0},"transitionNodeID":null,"children":[{"id":"0:30","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":564.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:32","name":"bearded-men-face-hipster-character-vector-14648253","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":43.0,"width":29.0,"x":1236.0,"y":566.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fa88d58c5f0e4e19ea1f1da0bc095f753c04260c","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:28.png"},{"pbdfType":"screen","id":"0:20","name":"person/4","convert":true,"type":null,"designNode":{"id":"0:20","name":"person/4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":282.0},"transitionNodeID":null,"children":[{"id":"0:21","name":"Group 7","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":282.0},"transitionNodeID":null,"children":[{"id":"0:22","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":282.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:24","name":"MV5BMTc0MzY2NjE0Nl5BMl5BanBnXkFtZTYwMDkxMDY0._V1_UY256_CR4,0,172,256_AL_","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":62.0,"width":41.0,"x":1230.0,"y":282.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"da827996130fb49beae52d638023a3c521add634","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:20.png"},{"pbdfType":"screen","id":"0:15","name":"person/8","convert":true,"type":null,"designNode":{"id":"0:15","name":"person/8","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":141.0},"transitionNodeID":null,"children":[{"id":"0:16","name":"Group 9 Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":141.0},"transitionNodeID":null,"children":[{"id":"0:17","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":141.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:19","name":"download","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":42.0,"x":1229.0,"y":141.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"0ee38c205bd2ebee137b0ff0ba528cf791c37df6","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:15.png"},{"pbdfType":"screen","id":"0:10","name":"person/6","convert":true,"type":null,"designNode":{"id":"0:10","name":"person/6","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":0.0},"transitionNodeID":null,"children":[{"id":"0:11","name":"Group 11","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":0.0},"transitionNodeID":null,"children":[{"id":"0:12","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":0.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:14","name":"MV5BMjAwMzc5OTEzOF5BMl5BanBnXkFtZTgwMDc5ODU3MTE@._V1_UX172_CR0,0,172,256_AL_","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":41.0,"x":1230.0,"y":0.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"d3bd9ca71b3fe97e05ddf694a700390c236d4c38","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:10.png"},{"pbdfType":"screen","id":"0:2","name":"icons/tab bar/home","convert":true,"type":null,"designNode":{"id":"0:2","name":"icons/tab bar/home","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":100.0,"y":264.0},"transitionNodeID":null,"children":[{"id":"0:3","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":false,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":104.0,"y":268.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:8","name":"Shape","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5329999923706055,"g":0.5661500096321106,"b":0.6499999761581421,"a":1.0}}],"children":[{"id":"0:6","name":"Subtract","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.8549019694328308,"g":0.8549019694328308,"b":0.8549019694328308,"a":1.0}}],"children":[{"id":"0:4","name":"Path","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":12.44444465637207,"width":23.33333396911621,"x":104.0,"y":270.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[],"imageReference":null,"pbdfType":null},{"id":"0:5","name":"Rectangle","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.6499999761581421,"g":0.578499972820282,"r":0.5525000095367432},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":5.689725875854492,"width":8.836241722106934,"x":116.1908950805664,"y":274.412353515625},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5525000095367432,"g":0.578499972820282,"b":0.6499999761581421,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":0.8999999761581421,"rectangleCornerRadii":null,"pbdfType":null}],"booleanOperation":null,"type":"BOOLEAN_OPERATION","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":100.0,"width":100.0,"x":104.0,"y":270.0},"imageReference":null,"pbdfType":null},{"id":"0:7","name":"Path","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":12.169487953186035,"width":3.1111111640930176,"x":124.22222137451172,"y":278.83050537109375},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[],"imageReference":null,"pbdfType":null},{"id":"0:9","name":"Path","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":7.115451812744141,"width":14.0,"x":108.66666412353516,"y":280.7734375},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[],"imageReference":null,"pbdfType":null}],"booleanOperation":null,"type":"BOOLEAN_OPERATION","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":21.0,"width":23.33333396911621,"x":104.0,"y":270.0},"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:2.png"}]}],"miscPages":[],"azure_container_uri":""} \ No newline at end of file diff --git a/lib/interpret_and_optimize/services/pb_platform_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_linker_service.dart index 9c4865f7..22cad2a0 100644 --- a/lib/interpret_and_optimize/services/pb_platform_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_linker_service.dart @@ -1,5 +1,7 @@ +import 'package:parabeac_core/generation/semi_constant_templates/responsive_layout_builder_template.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'package:parabeac_core/generation/semi_constant_templates/orientation_builder_template.dart'; class PBPlatformOrientationLinkerService { static final PBPlatformOrientationLinkerService _pbPlatformLinkerService = @@ -29,6 +31,19 @@ class PBPlatformOrientationLinkerService { _platforms.add(tree.data.platform); _orientations.add(tree.data.orientation); + // Add orientation builder template to the project + // if there are more than 1 orientation on the project + if (hasMultipleOrientations()) { + tree.rootNode.currentContext.project.genProjectData + .addTemplate(OrientationBuilderTemplate()); + } + // Add responsive layout builder template to the project + // if there are more than 1 plataform on the project + if (hasMultiplePlatforms()) { + tree.rootNode.currentContext.project.genProjectData + .addTemplate(ResponsiveLayoutBuilderTemplate()); + } + addToMap(tree); } From 9979c61d8733c1ea80a240ce6030896c90893dcb Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 29 Apr 2021 16:47:47 -0600 Subject: [PATCH 009/404] Removed unecessary TESTJSON folder --- TESTJSON/example.json | 33993 ---------------------------------------- TESTJSON/temp.json | 1 - 2 files changed, 33994 deletions(-) delete mode 100644 TESTJSON/example.json delete mode 100644 TESTJSON/temp.json diff --git a/TESTJSON/example.json b/TESTJSON/example.json deleted file mode 100644 index 5f96886b..00000000 --- a/TESTJSON/example.json +++ /dev/null @@ -1,33993 +0,0 @@ -{ - "projectName": "example", - "pbdfType": "project", - "id": "c056f644-e132-461b-84d6-9b3abcacfd0c", - "_class": "sharedStyle", - "do_objectID": "0848D478-81B0-415D-AC7C-FE13BE3A6BFD", - "name": "3Text3IndigoText116RightAlign", - "value": { - "_class": "style", - "do_objectID": "86774DC8-3409-4ECA-B674-E7E5E53BB974", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 5, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Regular", - "size": 16 - } - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "maximumLineHeight": 22, - "minimumLineHeight": 22, - "allowsDefaultTighteningForTruncation": 0, - "alignment": 1 - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.796078431372549, - "green": 0.1882352941176471, - "red": 0.5176470588235293 - }, - "kerning": -0.4000000059604645 - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pages": [ - { - "pbdfType": "design_page", - "id": "901e015d-2171-43ed-b8cd-8eedc5996b91", - "name": "Symbols", - "convert": true, - "screens": [ - { - "pbdfType": "screen", - "id": "a1ca9316-82b5-4270-b143-97575f0ec1d0", - "name": "SmallMajorCard", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Majors Overview", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - }, - "io.magicsketch.mirror": { - "highestQuality": -1 - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "header", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 375, - "x": 0, - "y": 0 - }, - "id": "3D096DF9-6442-4435-8B8F-E3AAC1B51E62", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "04DFC884-2240-4FD2-B69E-02C56B9BB460", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 0, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 375, - "x": 0, - "y": 0 - }, - "id": "D5F53318-78C2-443B-A0E4-62ED5644FEF6", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "3E99742C-458B-4E6B-88BE-8AA8CCE14BD6", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.207843137254902 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - }, - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.2078431372549019 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.2078431372549019 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "userScore", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 25, - "width": 70, - "x": 154, - "y": 51 - }, - "id": "8837475A-6727-4C29-82A4-F3412CE5687C", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4902C688-72C2-46D9-BA06-99C2FEAAF725", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "285", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "285", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 3, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 21 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 5}, {38, 16}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 25, - "width": 40, - "x": 0, - "y": 0 - }, - "id": "31FDA500-C98C-4383-B2B5-FC32759643F2", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4988E1EC-1EB3-4EAD-8B2B-4072F6495D57", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 21 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "starIcon", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 22, - "width": 22, - "x": 48, - "y": 2 - }, - "id": "30497D37-61E4-49F9-A617-0BCB56329DE4", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/7dc57eea260f608d09f997083c71f337eda203ca.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "21C0BBC5-9448-4B93-8B15-D9143D9D00E0", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "bellIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 30, - "width": 25.16129032258065, - "x": 16.99999999999998, - "y": 48 - }, - "id": "FD368E38-041A-4075-8FA9-072839FAF85C", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/bb842254e588c527f4071dda96f86e1a2fd87a00.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "30A69901-98CF-41C9-8F46-6C1BDEDD5B31", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "profileIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 34, - "width": 34, - "x": 326, - "y": 48 - }, - "id": "407DEF01-EE38-4546-9C87-1E6A51B66146", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "64AC93AD-B346-42F7-ADEA-702566114106", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Recommended Majors", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Recommended Majors", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 18, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {177, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 179, - "x": 17, - "y": 289 - }, - "id": "BDE3C25F-E16A-443F-886C-674C4334C0E3", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6AAD8DB3-01FC-4157-BA6E-2360E34D220C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Favorites", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Favorites", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 9, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {74, 14}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 75, - "x": 17, - "y": 166 - }, - "id": "A6E38EB0-3205-46BD-A51D-161C9948433C", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "DDDED71F-A840-4CB5-A9AC-719725D8DAF1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "SmallMajorCard", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [ - { - "overrideName": "B7235FC1-37B3-4948-AC8A-02BB2FC6F00B/3DEEC8AC-A192-4E9B-93C7-99F06921F282/E05F3922-7519-44D5-AE71-F903DCFC7581_layerStyle", - "do_objectID": null, - "value": "3EF9F3E0-996F-4084-BDD7-463EFEF0D844" - } - ], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 17, - "y": 199 - }, - "id": "FA945EAE-A00B-43FD-AE9E-B22BFAC7AF59", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E548AB9D-495B-4DAE-A735-7E6DBCDB79E7", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "SmallMajorCard Copy", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [ - { - "overrideName": "B7235FC1-37B3-4948-AC8A-02BB2FC6F00B/3DEEC8AC-A192-4E9B-93C7-99F06921F282/E05F3922-7519-44D5-AE71-F903DCFC7581_layerStyle", - "do_objectID": null, - "value": "3EF9F3E0-996F-4084-BDD7-463EFEF0D844" - } - ], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 195, - "y": 199 - }, - "id": "E3FC77BB-459D-4A8C-B34E-CAFC62C551B6", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4099D0C9-CA8D-4C99-9D3D-8744B181D41F", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "1. Bars / 2. Top Bar / 2. Large / Heading + Search", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 40, - "width": 113, - "x": 15, - "y": 113 - }, - "id": "0488D87A-251E-4DBB-8B34-65E79159236F", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "ABEB9CAF-C965-49E4-85A8-FD5A4482AC86", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "🅰️ Heading", - "nameIsFixed": true, - "resizingConstraint": 41, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": "4475D330-67E5-4F54-AA9A-872C355EA16D", - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.invisionlabs.duplicate": { - "type-duplicate": { - "title": "Advertising", - "action": "article", - "options": { - "section": "advertising", - "type": "title" - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Majors", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 6, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 32 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.3618807196617126, - "green": 0.1713331937789917, - "red": 0.01447581406682729 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "maximumLineHeight": 40, - "minimumLineHeight": 40, - "alignment": 0 - }, - "kerning": 0.6240000000000001 - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{2, 6}, {109, 31}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 40, - "width": 113, - "x": 0, - "y": 0 - }, - "id": "08B25671-7098-4E58-A78D-12A6BBD73714", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "85F610A3-94BD-438B-9495-533E4F18A209", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 32 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.3618807196617126, - "green": 0.1713331937789917, - "red": 0.01447581406682729 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "maximumLineHeight": 40, - "minimumLineHeight": 40, - "alignment": 0 - }, - "kerning": 0.6240000000000001 - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "SmallMajorCard", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 16, - "y": 326 - }, - "id": "AE25D6D2-3E3F-4F4A-ABA3-8F67C2B453E8", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F15B060C-CDFD-4A23-9CF2-06A9616F03C5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "SmallMajorCard Copy 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 16, - "y": 419 - }, - "id": "500B989E-4E28-44D6-A824-8F9E28FE5110", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "15D901F6-0D2E-44B5-93BD-392DAF934390", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "SmallMajorCard Copy 3", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 194, - "y": 419 - }, - "id": "79EA7918-1D80-4D39-A25E-219CB308BE35", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "C59E8323-0CE1-4BBA-B997-65EF6416703B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "SmallMajorCard Copy", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 194, - "y": 326 - }, - "id": "5607F1E5-E776-448E-B553-B145B5365E1F", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B7795373-B7C5-4DFB-AB95-E0B591F9A8B9", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Most Popular Majors", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Most Popular Majors", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 19, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {163, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 164, - "x": 17, - "y": 516 - }, - "id": "B3C9B48B-3DC9-4BB0-9192-C639BC96C97E", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "93AF3420-65D1-4C6B-8A8B-35FD0BB94960", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "SmallMajorCard", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 16, - "y": 549 - }, - "id": "C09DDE33-9148-4463-AF1F-E54492A60D80", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4FC81641-3BEF-4EFF-96DF-7E5E15AFE78D", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "SmallMajorCard Copy 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 17, - "y": 642 - }, - "id": "F48A588A-0CDF-45CC-AED5-47FE9D8FC0C3", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F1A19F6A-BEC1-4F58-B99A-F61A24F1368F", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "SmallMajorCard Copy 3", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 195, - "y": 642 - }, - "id": "3EE91335-877D-40F6-8B3D-819CB678795D", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6E212CD8-7B97-493E-81D8-8096BDEB79CD", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "SmallMajorCard Copy", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 194, - "y": 549 - }, - "id": "670E935D-31C3-4E1A-8562-34655859FAC1", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E57087FE-2F15-4F2C-AC0A-F26408F722FB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Advanced Search", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Advanced Search", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 15, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 14 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.9490196078431372, - "green": 0.5568627450980396, - "red": 0.211764705882353 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 1 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{0, 3}, {114, 11}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 16, - "width": 115, - "x": 245, - "y": 127 - }, - "id": "2F2A173C-F19B-4D5A-978E-3F12106B4137", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "86C3C36E-BE2C-4F24-8B15-BFE3D2A205D6", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 14 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.9490196078431372, - "green": 0.5568627450980396, - "red": 0.211764705882353 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 1 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "normal", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.bohemiancoding.sketchtool.detach": { - "symbolInstance": { - "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 93, - "width": 375, - "x": 0, - "y": 724 - } - }, - "symbolMaster": { - "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", - "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" - } - }, - "com.sketch.detach": { - "symbolInstance": { - "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 93, - "width": 375, - "x": 0, - "y": 724 - } - }, - "symbolMaster": { - "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", - "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 56, - "width": 302, - "x": 40, - "y": 734 - }, - "id": "68CA9079-975B-41F8-918A-81F81C663A89", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F71BC2DA-F20D-49FC-8AA1-76DD21DFB8A9", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "homeicon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 24.2734375, - "width": 26, - "x": 0, - "y": 16.86328125 - }, - "id": "81B176D5-B951-400A-A3F9-C23398FD71FA", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/724477925ebd536321fbadee7e227cfd057eb0f5.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "D856B0FA-B9DE-497B-A296-07C6A94FAADC", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7294117647058823, - "green": 0.6235294117647059, - "red": 0.5843137254901961 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "BBD21E46-AD9D-4372-AE85-42558046DA42", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "stats", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "BBD21E46-AD9D-4372-AE85-42558046DA42", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 24, - "width": 24, - "x": 208, - "y": 19 - }, - "id": "97759941-CDEC-4124-BD75-CF252BDF31A9", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/791dd23b4cf727cd2ad676896de2196a29d57e2d.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "682EFF94-01D4-4882-9F1D-36459ECB1718", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "plus-icon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 56, - "width": 50.90909090909091, - "x": 122.0000000000001, - "y": 0 - }, - "id": "D2A3113D-06F0-4E2D-BAFF-828FE420A825", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/c4eea6263c1c1732dcb7a96694a80dd390a1ff7d.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "78AB3AC4-4205-4A7C-B713-9413D90C1963", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "not published", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 23.33333333333333, - "width": 23.33333333333333, - "x": 69, - "y": 18 - }, - "id": "CF548824-145B-4B9B-91FF-2780A4350CC0", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5c0161e4cd699ec44a35f72b3b4b529f464c6f94.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "3119424D-99FC-4F53-82F8-B778935443EA", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "learn", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 21, - "width": 24, - "x": 278, - "y": 23 - }, - "id": "7192C076-B6DB-40AA-92C5-AC2CE1217A9F", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5ce1816426a25e74eb636fbaa1e06a6627b7d7ee.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "7648BBE9-332A-41E8-BBEA-C55FDA73F9FF", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "CLASS_NAME": null, - "type": "artboard", - "includeInCloudUpload": true, - "includeBackgroundColorInExport": true, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "layout": null, - "grid": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 812, - "width": 375, - "x": 690, - "y": -295 - }, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "id": "22155B2E-9044-4DCD-A0D1-C5656655323A", - "hasBackgroundColor": true, - "isFlowHome": false, - "resizesContent": false, - "presetDictionary": { - "height": 812, - "offersLandscapeVariant": 1, - "name": "iPhone X", - "width": 375, - "allowResizedMatching": 1 - }, - "visible": true, - "style": { - "_class": "style", - "do_objectID": "274DBB7E-AB41-4ED0-991E-481F1A1008BD", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "artboard" - }, - "azure_blob_uri": "/A1CA9316-82B5-4270-B143-97575F0EC1D0.png" - }, - { - "pbdfType": "screen", - "id": "7abb7146-7156-4fa4-8e2d-f816fd51ed27", - "name": "icons/tabbar/home", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "jpg", - "name": "", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Landing Page", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - }, - "io.magicsketch.mirror": { - "highestQuality": -1 - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "iPhone X Blue@3x", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 216, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 413, - "width": 221, - "x": 78, - "y": 106 - }, - "id": "91EDA7BB-F048-429A-A4AB-0920FF86EE3F", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/d9ac02d78c4b82b0cacb3dc59abb1eaab6827753.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "45D00E60-3AFA-4221-8AC0-965CE88C0846", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 0, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 271, - "width": 375, - "x": 0, - "y": 541 - }, - "id": "9F5E1EE0-3953-4C24-9E5E-036025B119D6", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4F65EB72-BD53-4B00-8808-A8166D6B5FCA", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "A new way to learn a", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "A new way to learn about careers", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 32, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 16 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.3618807196617126, - "green": 0.1713331937789917, - "red": 0.01447581406682729 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - }, - "kerning": 0.2222222222222222 - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{9, 3}, {273, 16}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 19, - "width": 292, - "x": 41, - "y": 563 - }, - "id": "11EF6BCF-F96E-4BBA-9A76-DEAF21E67591", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "DF0B020C-E294-4478-B0BD-A53451DC2414", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 16 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.3618807196617126, - "green": 0.1713331937789917, - "red": 0.01447581406682729 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - }, - "kerning": 0.2222222222222222 - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Inspyred provides re", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Inspyred provides resources to help you make the best decisions.", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 64, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Medium", - "size": 13 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.6196078431372549, - "green": 0.5254901960784314, - "red": 0.4666666666666667 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "maximumLineHeight": 20, - "minimumLineHeight": 20, - "alignment": 2 - }, - "kerning": 0.111 - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{4, 5}, {228, 33}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 40, - "width": 235, - "x": 70, - "y": 592 - }, - "id": "1BA3BFB1-0BBC-426F-BDFD-52F4F96A051B", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "285058DB-F572-4EA0-9A96-E6AB58EF6A87", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Medium", - "size": 13 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.6196078431372549, - "green": 0.5254901960784314, - "red": 0.4666666666666667 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "maximumLineHeight": 20, - "minimumLineHeight": 20, - "alignment": 2 - }, - "kerning": 0.111 - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Main-button", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 42, - "width": 288, - "x": 44, - "y": 664 - }, - "id": "4E64D8E6-3CA3-4FD8-B4A2-00F37A01D3DD", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "46BA520C-4552-476C-B9D6-DAC71E3100FD", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Create Account", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 42, - "width": 288, - "x": 0, - "y": 0 - }, - "id": "9CDBDB86-8D3E-4195-85C8-6C277B887D2F", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "A4DBF255-AC62-4732-ABFE-3F107AAF944A", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": "352ED728-3274-4B9B-A8E1-519933787FAD", - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 100, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 100, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 100, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 100, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 100, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 42, - "width": 288, - "x": 0, - "y": 0 - }, - "id": "6A00ABC1-630E-4D11-9E85-B6AFF6327E7D", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "2760AE32-E436-4CE7-BE88-6F7128034496", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.2078431372549019 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Sign Up", - "nameIsFixed": true, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": "447EE00B-5E7B-44E6-A556-1E2D6B154DF8", - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Sign Up", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 7, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Medium", - "size": 16 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - }, - "MSAttributedStringTextTransformAttribute": 1 - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{1, 3}, {65, 13}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 19, - "width": 66, - "x": 111, - "y": 12 - }, - "id": "6C3213BD-D9C0-4385-8070-D237D233D1DA", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "29B129BE-4C28-4107-AAF1-F93CD824C91B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Medium", - "size": 16 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "MSAttributedStringTextTransformAttribute": 1, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Create Account", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 42, - "width": 288, - "x": 44, - "y": 725 - }, - "id": "4928E2BE-EDE9-404C-8995-B7C470D3B523", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "DBB029E0-E7A9-4CBA-9049-E791D44B7B1F", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": "352ED728-3274-4B9B-A8E1-519933787FAD", - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 100, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 100, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 100, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 100, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 100, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 42, - "width": 288, - "x": 0, - "y": 0 - }, - "id": "F478F1A9-7453-4631-85DD-85F38C4AC994", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "0F6F633A-E26B-4423-A195-23505F8930A7", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 0, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Log in", - "nameIsFixed": true, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": "447EE00B-5E7B-44E6-A556-1E2D6B154DF8", - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Log in", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 6, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Medium", - "size": 16 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.4921875, - "green": 0.4921875, - "red": 0.4921875 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - }, - "MSAttributedStringTextTransformAttribute": 1 - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{1, 3}, {53, 13}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 19, - "width": 55, - "x": 116.5, - "y": 12 - }, - "id": "3E3BE211-8D70-4F7C-8FA2-1929F6008911", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "01CDCF6A-40F6-4E2D-9F80-3A765CED87ED", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Medium", - "size": 16 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.4921875, - "green": 0.4921875, - "red": 0.4921875 - }, - "MSAttributedStringTextTransformAttribute": 1, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "header", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 375, - "x": 0, - "y": 0 - }, - "id": "63251011-40E5-4A48-873F-1B5B7F32B840", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "63A6B68C-880C-4CC6-8138-77FE3802D23A", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 0, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 375, - "x": 0, - "y": 0 - }, - "id": "99548B48-5932-4ED7-8688-3D5861018474", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "BCBC34A6-9894-4912-B1DD-47591462EB25", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.207843137254902 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - }, - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.2078431372549019 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "userScore", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 25, - "width": 70, - "x": 153, - "y": 51 - }, - "id": "9C99686A-6AF1-4DC2-A5A6-D418EF354490", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "A304CF40-9A91-4A7A-96C0-48ABD4BD7956", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "285", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "285", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 3, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 21 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{1, 5}, {38, 16}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 25, - "width": 40, - "x": 0, - "y": 0 - }, - "id": "29326099-B5C1-4B12-9A66-B98D0D75C21C", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F83E766B-7657-429A-AF76-A4126C261CDE", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 21 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "starIcon", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 22, - "width": 22, - "x": 48, - "y": 2 - }, - "id": "B2761F8E-7B41-4833-A0E8-7F6082DD5C12", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/7dc57eea260f608d09f997083c71f337eda203ca.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F7742F48-B8F2-4433-8A53-01EAAE777032", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "bellIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 30, - "width": 25, - "x": 17, - "y": 48 - }, - "id": "FF62F74F-C6A7-4EB0-ACC5-8E3682B5D5F9", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/bb842254e588c527f4071dda96f86e1a2fd87a00.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "44C3DDF1-0F00-4EB7-ABD8-F8BDE9E8C217", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "profileIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 34, - "width": 34, - "x": 326, - "y": 48 - }, - "id": "C0F28883-43D1-47F0-8FE4-68E054EE17D6", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "1F25C912-EA13-4DD4-88C3-91C6984220C1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "CLASS_NAME": null, - "type": "artboard", - "includeInCloudUpload": true, - "includeBackgroundColorInExport": true, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "layout": null, - "grid": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 812, - "width": 375, - "x": 2154, - "y": -295 - }, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "id": "36EB4CE8-41DD-4EDE-A4BD-ED88D043D9F1", - "hasBackgroundColor": true, - "isFlowHome": true, - "resizesContent": false, - "presetDictionary": { - "width": 375, - "offersLandscapeVariant": 1, - "height": 812, - "allowResizedMatching": 1, - "name": "iPhone X" - }, - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E72ACE4B-4154-4BAC-BBD0-FC04480E49F5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "artboard" - }, - "azure_blob_uri": "/7ABB7146-7156-4FA4-8E2D-F816FD51ED27.png" - }, - { - "pbdfType": "screen", - "id": "53d04c05-9e5d-4f7a-8765-7dbea892d0b5", - "name": "person/6", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "jpg", - "name": "", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Community Groups", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - }, - "io.magicsketch.mirror": { - "highestQuality": -1 - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "header", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.bohemiancoding.sketchtool.detach": { - "symbolInstance": { - "do_objectID": "C7D593F6-8A76-4439-9684-505554F82229", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 375, - "x": 0, - "y": 0 - } - }, - "symbolMaster": { - "do_objectID": "ADF19C17-3F52-4FE3-B207-2A6E6AC2DB95", - "symbolID": "65B0D541-BC41-4E38-81E3-41E0946BC70B" - } - }, - "com.sketch.detach": { - "symbolInstance": { - "do_objectID": "C7D593F6-8A76-4439-9684-505554F82229", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 375, - "x": 0, - "y": 0 - } - }, - "symbolMaster": { - "do_objectID": "ADF19C17-3F52-4FE3-B207-2A6E6AC2DB95", - "symbolID": "65B0D541-BC41-4E38-81E3-41E0946BC70B" - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 375, - "x": 0, - "y": 0 - }, - "id": "3A37FC24-9DA4-4A94-AB11-5183101C9BB2", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "BD13C2FD-BDF7-4499-8BCC-98200B921102", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 0, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 375, - "x": 0, - "y": 0 - }, - "id": "E879766B-336D-448D-A583-DAFCD0349D06", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "7781FF84-5E04-445D-B269-2B4E52473CB3", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.2078431372549019 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.207843137254902 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "userScore", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 25, - "width": 70, - "x": 153, - "y": 51 - }, - "id": "F98C8691-2415-4182-A967-9C044B8A7EFE", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "9788D9D7-A7D5-413D-BC43-A87A113981BF", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "285", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "285", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 3, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 21 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 5}, {38, 16}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 25, - "width": 40, - "x": 0, - "y": 0 - }, - "id": "F23BD062-473C-4CA4-A6B5-22178319C9E2", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "D642968B-DD1F-4EB7-ABF0-7E3A2596EF6A", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 21 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "starIcon", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 22, - "width": 22, - "x": 48, - "y": 2 - }, - "id": "16416ED0-5F5A-4910-B0AD-60E53BCAA1A0", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/7dc57eea260f608d09f997083c71f337eda203ca.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "06DE097D-7125-4375-BDB7-A32DDBA2A887", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "bellIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 29.2258064516129, - "width": 25.16129032258065, - "x": 16.99999999999998, - "y": 48.77419354838709 - }, - "id": "63F24305-CB55-4B5B-A073-D38836E0927F", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/1ab87eea21615010a2576c5a46416a88641231ec.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "2350971C-AD03-4398-B906-228AD1248B5A", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "profileIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 34, - "width": 34, - "x": 326, - "y": 48 - }, - "id": "91B172C3-266A-4631-85A9-53357F95CAE3", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "1CC75F68-D52B-4597-B22A-03E9C13C5D6D", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Your Groups", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Your Groups", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 11, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{0, 4}, {97, 15}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 98, - "x": 17, - "y": 111 - }, - "id": "67022F73-66AB-4888-99EE-0A014880FFE5", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "2D7E06F9-FA19-4C76-BED0-8813A7741194", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "More Groups", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "More Groups", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 11, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 4}, {101, 15}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 102, - "x": 17, - "y": 299 - }, - "id": "8781D32E-2E85-4C2A-8FB7-AC969364CA09", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "2024D5D8-A0E6-4149-B95A-14FD08AE9268", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Cell1", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 124, - "width": 245, - "x": 17, - "y": 148 - }, - "id": "B79FE1C9-5B34-437B-9132-2581EB447D55", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "34F63DEA-F7C2-4809-9F16-6D2DD2E8CDC7", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 10, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 124, - "width": 245, - "x": 0, - "y": 0 - }, - "id": "6D3D3561-4E59-493E-85F4-272607A395AA", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "00126421-C6AE-446A-B98D-F77373FD8005", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "High School Group", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "High School Group", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 17, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {144, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 146, - "x": 14, - "y": 13 - }, - "id": "40C6CFBC-7962-497A-8D3D-3F4C43B0D5F1", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "651B9724-330B-4765-BC5B-27B749FE582F", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "People Group 1", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 89, - "x": 14, - "y": 68 - }, - "id": "01E8E835-9FED-487B-BB8C-E6895C19436F", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "3FE98165-00DA-4823-BB6C-C4536B928DA1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person 9", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [ - { - "overrideName": "D6CDCF6E-5E0B-4FD4-9EEC-11BEF7583021_symbolID", - "do_objectID": null, - "value": "" - } - ], - "scale": 1, - "symbolID": "00121EBB-86F2-4C74-8A1D-074B52B33010", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "CDAB5F56-F495-4512-BD9A-1DA67226ACBA", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "BCEA4D9D-4DE6-4CDA-AAF8-58943055C622", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person 9", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [ - { - "overrideName": "A268549D-9BCF-41CE-B386-6FFC1C85817B_symbolID", - "do_objectID": null, - "value": "530E093C-4A76-41F1-9482-08004D962CD5" - } - ], - "scale": 1, - "symbolID": "1E69FEC0-85F8-42BA-A987-F973EC2F19A8", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 24, - "y": 0 - }, - "id": "99F3048C-B378-4CBC-B6BB-F65F7922FD28", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "39C1D372-28A0-4AEB-A8DE-F1ABB723EE31", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person 9 copy", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [ - { - "overrideName": "A268549D-9BCF-41CE-B386-6FFC1C85817B_symbolID", - "do_objectID": null, - "value": "292AFD52-31A6-40B2-B087-3C35E9191616" - } - ], - "scale": 1, - "symbolID": "1E69FEC0-85F8-42BA-A987-F973EC2F19A8", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 48, - "y": 0 - }, - "id": "7C0FBBA7-8159-4646-B9E6-ACF888E27AEA", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F46EC120-54CD-4423-AFC2-639A1A0F629F", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Cell2", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 124, - "width": 245, - "x": 274, - "y": 148 - }, - "id": "F4F240C2-8169-48F4-9847-E2EA100E466D", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "EB9984DF-D61C-45A4-B61A-59C12C86B082", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 10, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 124, - "width": 245, - "x": 0, - "y": 0 - }, - "id": "8DFBAE27-3655-4D04-9801-20DBDE6BC2B0", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "03BF79D3-C3F9-484A-94D5-3BC57B4AD5CA", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Programming", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Programming", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 11, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {105, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 107, - "x": 26, - "y": 13 - }, - "id": "B9BE2B17-BEA2-44CB-95C8-9E30A067CFBF", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "78D56614-CF62-4103-8266-8C219A61C686", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "People Group 2", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 89, - "x": 26, - "y": 68 - }, - "id": "37511FBB-B56B-4147-8A66-0AC2D10F8B53", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "A03D03E3-AFE9-48F6-9DFE-6DA124466447", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person 9 copy 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "7ABF1A2D-5708-4024-81DA-F0C183CB18AA", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "068DAB0A-9AB7-4DAA-B9F4-2068B9C655B3", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person/5", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "29155DF5-855F-4948-9C6C-935F9F9DD81E", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "4C59C535-CE42-4D64-A52A-E67B51A66AB6", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F34DEB8E-9955-4560-89E2-40B2E80E24BC", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person/frame", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "9912193F-5440-41AC-BB51-C6001980B1CE", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "5E9D1FA5-635F-421B-A6E5-FD4DC43541EC", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person 9 copy 3", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 24, - "y": 0 - }, - "id": "340FDA42-D564-4545-94C2-1158AE4B6F7C", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F6A4FBEA-7939-4641-A4E6-51944A3E7D45", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person/5", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "97736C0F-6E1F-4671-912F-003C97ACDE40", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "9CB2FBCF-7014-4C54-9768-D7C5343D1A8A", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "FC663A2E-AD33-404F-B315-BCDDB7AF3DB9", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person/frame", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "44826B0C-228E-4CDB-88DD-EAE3F11211C1", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "C8D7E19F-6D3B-4FE1-AD33-527CE0DCB142", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person 9 copy 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 48, - "y": 0 - }, - "id": "5629672A-EB36-4712-AEA9-17D262153C00", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4FB1487E-AFF3-4937-AEEF-A5AB207B34FC", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person/5", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "477112E3-2915-42AA-96E2-BFD71521C33D", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "4008399E-04C4-4C36-83D8-3E101BCB21F9", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4AFF161F-45D7-487E-B847-E2807F941DDF", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person/frame", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "C289F2E4-82A8-4453-A2C6-E80A5562602B", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "2D33DC74-0136-41FB-A9FC-8B2916CA1F5C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "groups", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 344, - "width": 358, - "x": 17, - "y": 372 - }, - "id": "693EA2A3-1F1D-4913-B010-059737882017", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "0C0AD29A-0597-44EB-8D8A-BCF993CE1F57", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Algorithms", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Algorithms", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 10, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{0, 3}, {86, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 87, - "x": 0, - "y": 0 - }, - "id": "8CDC477E-FF4F-42DC-9259-C621C3F52632", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6710AA96-32A4-4D98-92DF-99B2BD3BC559", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Nursing", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Nursing", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 7, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {60, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 62, - "x": 0, - "y": 65 - }, - "id": "AE9DFE1E-3AE8-4546-81A6-CAB26D5772B2", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "76C0FACE-B6A4-4077-A1C3-7C34456821C0", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Dog Photos", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Dog Photos", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 10, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 4}, {88, 16}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 90, - "x": 0, - "y": 130 - }, - "id": "A9619FE1-6724-489E-88AD-03649DD72DCA", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "88A7AB46-FDEE-4D0B-B2F5-0448475EA3CD", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Sports", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Sports", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 6, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{0, 4}, {51, 15}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 52, - "x": 0, - "y": 195 - }, - "id": "AB5B3E70-12AA-42AD-924A-25F385BABFBE", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "BBBA777C-4F22-4787-B73D-244FDDF6E4FA", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Band", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Band", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 4, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 4}, {38, 13}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 41, - "x": 0, - "y": 259 - }, - "id": "0BE64048-7FCC-472D-9DB0-9382BA761844", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "7F783BF9-2DE4-436F-9B76-DEFE802A7DA1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Party time", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Party time", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 10, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {80, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 82, - "x": 0, - "y": 324 - }, - "id": "B7486DA7-30A6-4078-98A3-569D5C181043", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F16ED156-1A04-4A49-928C-34F73105EAE5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Line Copy", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": false, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0.49999999999999994}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 2, - "width": 354, - "x": 4, - "y": 40 - }, - "id": "C3124E8F-BFCC-4BAF-905E-D65A3770CD26", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "5BD035B8-4865-49FD-9433-7F344141E333", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 0, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": false, - "dashPattern": [], - "lineCapStyle": 2, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7843137254901961, - "green": 0.7568627450980392, - "red": 0.7372549019607844 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Line Copy 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": false, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0.49999999999999994}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 2, - "width": 354, - "x": 4, - "y": 105 - }, - "id": "15D6BF49-8EF7-4725-9CC0-696BEF2B2105", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "22FE69B4-FFF9-4DCE-914B-A5C8914EE9FB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 0, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": false, - "dashPattern": [], - "lineCapStyle": 2, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7843137254901961, - "green": 0.7568627450980392, - "red": 0.7372549019607844 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Line Copy 3", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": false, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0.49999999999999994}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 2, - "width": 354, - "x": 4, - "y": 170 - }, - "id": "DAF36D0C-277E-449E-BF19-E245BDC03E8C", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "946D5869-99AC-4129-BD81-94ABA295B2A6", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 0, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": false, - "dashPattern": [], - "lineCapStyle": 2, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7843137254901961, - "green": 0.7568627450980392, - "red": 0.7372549019607844 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Line Copy 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": false, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0.49999999999999994}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 2, - "width": 354, - "x": 4, - "y": 235 - }, - "id": "CB2AD56A-78E0-4456-BA5B-CDFA26756CC0", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "2314069D-98E1-4FCE-A1FE-F3E0B245E0A9", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 0, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": false, - "dashPattern": [], - "lineCapStyle": 2, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7843137254901961, - "green": 0.7568627450980392, - "red": 0.7372549019607844 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Line Copy 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": false, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0.49999999999999994}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.49999999999999994}", - "curveMode": 1, - "curveTo": "{0, 0.49999999999999994}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 2, - "width": 354, - "x": 4, - "y": 299 - }, - "id": "C8876F24-8460-4D10-8987-A886C2258E14", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "202AD07B-86D8-4318-95E8-ECB67EC2F10A", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 0, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": false, - "dashPattern": [], - "lineCapStyle": 2, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7843137254901961, - "green": 0.7568627450980392, - "red": 0.7372549019607844 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Line", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": false, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.112, 0.49999999999999933}", - "curveMode": 1, - "curveTo": "{0.112, 0.49999999999999933}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.112, 0.49999999999999933}", - "curveMode": 1, - "curveTo": "{0.112, 0.49999999999999933}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 1, - "width": 187.5, - "x": 0, - "y": 337 - }, - "id": "E7FC09F6-0B0F-409D-9D25-5C6187009ABB", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E1FEC734-9C06-4233-94FA-577811F35BB3", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 0, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": false, - "dashPattern": [], - "lineCapStyle": 2, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 0.5176470588235293, - "red": 0 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 3 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "normal", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.bohemiancoding.sketchtool.detach": { - "symbolInstance": { - "do_objectID": "C441BE9F-7AE4-4D86-8C5E-1FE28B1B146F", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 93, - "width": 375, - "x": 0, - "y": 719 - } - }, - "symbolMaster": { - "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", - "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" - } - }, - "com.sketch.detach": { - "symbolInstance": { - "do_objectID": "C441BE9F-7AE4-4D86-8C5E-1FE28B1B146F", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 93, - "width": 375, - "x": 0, - "y": 719 - } - }, - "symbolMaster": { - "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", - "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 56, - "width": 302, - "x": 40, - "y": 729 - }, - "id": "E5EBC598-D3D9-4F0B-A8AF-93C9283840B6", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "41E1E1AE-B64F-4DC0-B27E-9C52D99E7875", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "homeicon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 24.2734375, - "width": 26, - "x": 0, - "y": 16.86328125 - }, - "id": "59F5955C-E074-4E0C-958E-A4877439B42A", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/724477925ebd536321fbadee7e227cfd057eb0f5.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "63D4D0F5-909A-4C9A-8846-96D6CEEDD57A", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7294117647058823, - "green": 0.6235294117647059, - "red": 0.5843137254901961 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "stats", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 24, - "width": 24, - "x": 208, - "y": 19 - }, - "id": "36E1159D-0BCC-4608-AEDF-668E08643457", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/791dd23b4cf727cd2ad676896de2196a29d57e2d.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "1A0788EB-E8B4-4442-8217-A2617525798B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "plus-icon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 56, - "width": 50.90909090909091, - "x": 122, - "y": 0 - }, - "id": "38142621-3AFF-4B56-B147-ECB7916D5CBF", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/c4eea6263c1c1732dcb7a96694a80dd390a1ff7d.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "30ACA845-DE4C-4776-A013-F5F4FB062ADE", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "22155B2E-9044-4DCD-A0D1-C5656655323A", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "not published", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "22155B2E-9044-4DCD-A0D1-C5656655323A", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 23.33333333333333, - "width": 23.33333333333333, - "x": 69, - "y": 18 - }, - "id": "A5FF612E-E3F3-4705-B566-022050D92A93", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5c0161e4cd699ec44a35f72b3b4b529f464c6f94.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "8D87A4E1-4AF3-416C-A4A9-593839693D6C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "learn", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 21, - "width": 24, - "x": 278, - "y": 23 - }, - "id": "AB138350-BAC4-4E1D-9E46-43C0105EDED5", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5ce1816426a25e74eb636fbaa1e06a6627b7d7ee.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "634B2EC5-3A62-4B27-809F-7C0BAF5CB06E", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Create New", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Create New", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 10, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 14 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.8862745098039215, - "green": 0.4823529411764704, - "red": 0.207843137254902 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "allowsDefaultTighteningForTruncation": 0, - "alignment": 0 - }, - "kerning": -0.224 - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{0, 3}, {72, 11}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 16, - "width": 72, - "x": 267, - "y": 114 - }, - "id": "BE18F369-3584-46BB-9F9F-E60EDC6BC64E", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "93574C40-E84A-482F-904D-EB8849A05625", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 14 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.8862745098039215, - "green": 0.4823529411764704, - "red": 0.207843137254902 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "allowsDefaultTighteningForTruncation": 0, - "alignment": 0 - }, - "kerning": -0.224 - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - } - ], - "CLASS_NAME": null, - "type": "artboard", - "includeInCloudUpload": true, - "includeBackgroundColorInExport": true, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "layout": null, - "grid": { - "_class": "simpleGrid", - "isEnabled": false, - "gridSize": 20, - "thickGridTimes": 10 - }, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 812, - "width": 375, - "x": 1679, - "y": -295 - }, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "id": "BBD21E46-AD9D-4372-AE85-42558046DA42", - "hasBackgroundColor": true, - "isFlowHome": false, - "resizesContent": false, - "presetDictionary": { - "allowResizedMatching": 1, - "offersLandscapeVariant": 1, - "name": "iPhone X", - "height": 812, - "width": 375 - }, - "visible": true, - "style": { - "_class": "style", - "do_objectID": "2CCDC855-B2FE-43FF-9023-384A0E8C46FA", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "artboard" - }, - "azure_blob_uri": "/53D04C05-9E5D-4F7A-8765-7DBEA892D0B5.png" - }, - { - "pbdfType": "screen", - "id": "b8f978e3-16b6-4278-b836-b67e3f123c68", - "name": "person/8", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "HomeScreenAlt", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "someElement/default", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "3156C515-06F6-428E-8A5B-CB8B85B1F7F4", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 560, - "width": 419, - "x": -5, - "y": 0 - }, - "id": "4E81F228-20E6-45BA-9864-1B6830B51F5E", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "9E2D66E8-3133-4F0D-95A3-090C3847C4E1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Top Stack Section", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 560, - "width": 414, - "x": 0, - "y": 50 - }, - "id": "64B9FF31-0809-4857-9A5E-E3F1E82A47BB", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6A4DFD07-4C2D-4232-BB6E-DB57556781D6", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Group 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 44, - "width": 258, - "x": 79, - "y": 81 - }, - "id": "DA7A85FF-BEC3-422D-B4C7-A0D6EAADF6E2", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E1BDF8D4-0E9B-4410-BB8B-7925F41F0A9A", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Noam Levine", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Noam Levine", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 11, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{6, 3}, {104, 14}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 115.7692307692308, - "x": 70.56410256410257, - "y": 0.4761904761904763 - }, - "id": "E4C1DD25-DED6-4DA3-98F5-94AE78F86827", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "5D394956-B0F8-4A48-B3AA-E8C276D8CD7C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Student at Hanks Hig", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Student at Hanks High School", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 28, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{13, 3}, {231, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 256.8974358974359, - "x": 0.5512820512820513, - "y": 23.52380952380953 - }, - "id": "0018EBA8-F3B8-4971-ADED-C455BCC732A3", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "3EEE6295-D658-4DAB-965F-B74CCAA48109", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Completion Graph", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 88, - "width": 131, - "x": 142, - "y": 235 - }, - "id": "D78502A3-1F0A-449D-9671-08651CA5C85F", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "2789C32A-D50A-46C6-BE25-12D4AC0D8B96", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 8.185654008438819, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "72%", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "72%", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 3, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 60.30155896069287 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{2, 15}, {115, 43}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 72, - "width": 131, - "x": 0, - "y": 0.117647058823529 - }, - "id": "B74C9066-66DE-4A79-A313-3F4CB8C486C8", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "96914655-3032-4836-9D2B-D7C642809CB7", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 8.375216522318453, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.9411764705882353, - "green": 0.4549019607843137, - "red": 0.2784313725490197 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.207843137254902 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 60.30155896069287 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Completed", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Completed", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 9, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 15.91291139240506 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 0.8, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{0, 3}, {81, 15}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 19, - "width": 91.36974789915965, - "x": 19.81512605042008, - "y": 68.44117647058823 - }, - "id": "A3D16E96-F0BA-4297-8FB6-E876A73200C7", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6F5203AE-C12D-481E-BDEA-DF553E8BBBEB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 8.375216522318453, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.9411764705882353, - "green": 0.4549019607843137, - "red": 0.2784313725490197 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.207843137254902 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 15.91291139240506 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 0.8, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "ScoreCard", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 128, - "width": 414, - "x": 0, - "y": 432 - }, - "id": "0002CDDE-C2AB-4063-8621-F9C29431D10A", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "DA4357B2-124E-48B9-81AB-340419E1BF11", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Score Bar@3x", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 216, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 128, - "width": 414, - "x": 0, - "y": 0 - }, - "id": "FC2F0364-7AC3-4544-88B1-4B5325E6BFF7", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/896d0b8336868d41380f511f76aaff0ff80b0986.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "786CF742-FD2C-4885-9698-B6ED4F3A2056", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Score: 285", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Score: 285", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 7, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 22 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.1996332757179576, - "green": 0.1996332757179576, - "red": 0.2154815051020408 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - }, - { - "_class": "stringAttribute", - "location": 7, - "length": 3, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 22 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.9333333333333333, - "green": 0.5372549019607842, - "red": 0.2078431372549019 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 3, - "textBehaviour": 1, - "glyphBounds": "{{6, 6}, {113, 16}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 26, - "width": 125.856, - "x": 144.072, - "y": 40.9504132231405 - }, - "id": "23B2A6D4-19C3-4998-835E-EE0EA730987A", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "156269BE-EF3F-47EC-A992-131FEAC1ABFB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 22 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.1996332757179576, - "green": 0.1996332757179576, - "red": 0.2154815051020408 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "profileIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 36, - "width": 38, - "x": 357, - "y": 0 - }, - "id": "4B59724C-6636-4A01-9194-ED2FA00779C1", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "ACFBAC63-A7D3-4E33-9BEF-9CD31D9621DC", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "bellIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 30, - "width": 28, - "x": 19, - "y": 3 - }, - "id": "289A647A-AC32-4A2E-B728-4834755FB106", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/1ab87eea21615010a2576c5a46416a88641231ec.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "02C7F5B6-61E8-4FA8-B219-F3040760A11B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Connect Facebook Button", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 342, - "x": 36, - "y": 610 - }, - "id": "A303AE9A-A3FD-48E7-9EB7-3D43C33D87DB", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F60AECE7-6562-4E32-AB5C-A7FC92986CCF", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 342, - "x": 0, - "y": 0 - }, - "id": "897E1F6A-D392-461A-A78A-648C89309CE9", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B0B03806-1FAD-4B94-921A-401C3F148C73", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Rectangle 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": true, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 30.5, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 30.5, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 30.5, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 30.5, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 100, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 342, - "x": 0, - "y": 0 - }, - "id": "AE753A74-1CAE-4B27-BCD7-0D38E72A9A4D", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B11425D9-E295-4191-9B89-B7E2722D0CF3", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - }, - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 0.6980392156862745, - "green": 0.4039215686274508, - "red": 0.2588235294117647 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Continue", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Connect facebook", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 16, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "paragraphSpacing": 2.299999952316284, - "alignment": 0 - }, - "MSAttributedStringTextTransformAttribute": 1 - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{0, 3}, {186, 14}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 186, - "x": 88, - "y": 21 - }, - "id": "7B262F2E-F2B8-4F32-BF45-ABD68C860FA6", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B486C1BB-1066-40E1-BF5C-9200A16788F3", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0, 0}", - "gradientType": 0, - "to": "{1, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.9137254901960784, - "green": 0.3529411764705881, - "red": 0.3568627450980389 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.9411764705882353, - "green": 0.4549019607843137, - "red": 0.2784313725490197 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "MSAttributedStringTextTransformAttribute": 1, - "paragraphStyle": { - "_class": "paragraphStyle", - "paragraphSpacing": 2.299999952316284, - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Page 1", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 61, - "x": 0, - "y": 0 - }, - "id": "252A7A3A-BD0B-4C7A-8156-06960F1624CA", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "CE757C0D-F861-4DF0-A811-9EC87BCF80A2", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 12.70833333333333, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Oval 5", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "constraints": { - "scaleFactor": 1, - "model_version": 0.1, - "aspectRatio": { - "model_version": 0.1, - "enabled": 1, - "multiplier": 60.93646, - "modelID": "constraint_a76df48e-bf62-4625-934e-d88b37589797", - "model_class": "ADModelConstraint", - "constant": 60.93646 - }, - "modelID": "viewConstraints_83e4874d-5168-4c05-9eb7-e242e4e7297a", - "model_class": "ADModelViewConstraints", - "automatic": 1 - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614237490000004, 1}", - "curveMode": 2, - "curveTo": "{0.22385762510000001, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385762510000001}", - "curveMode": 2, - "curveTo": "{1, 0.77614237490000004}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22385762510000001, 0}", - "curveMode": 2, - "curveTo": "{0.77614237490000004, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77614237490000004}", - "curveMode": 2, - "curveTo": "{0, 0.22385762510000001}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 61, - "width": 61, - "x": 0, - "y": 0 - }, - "id": "E2661B1C-876F-468C-A528-FC7A1ABBDE51", - "type": "oval", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "542D78E0-DAD6-4100-B2D3-EEA197358AB7", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 12.70833333333333, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 1.270833333333333 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.6980392156862745, - "green": 0.4039215686274508, - "red": 0.2588235294117647 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "oval" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Fill 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.94393217672507967, 0.55011276448004953}", - "curveMode": 1, - "curveTo": "{0.94393217672507967, 0.55011276448004953}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.94393217672507967, 0.55011276448004953}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.98806974609972453, 0.37028641604067547}", - "curveMode": 1, - "curveTo": "{0.98806974609972453, 0.37028641604067547}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.98806974609972453, 0.37028641604067547}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.64910632347157293, 0.37028641604067547}", - "curveMode": 1, - "curveTo": "{0.64910632347157293, 0.37028641604067547}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.64910632347157293, 0.37028641604067547}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.64910632347157293, 0.20342367881921516}", - "curveMode": 4, - "curveTo": "{0.64910632347157293, 0.25548471510470155}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.64910632347157293, 0.25548471510470155}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.81871913647686034, 0.16795308079445873}", - "curveMode": 4, - "curveTo": "{0.67659397806231703, 0.16795308079445873}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.81871913647686034, 0.16795308079445873}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.16791291024176927}", - "curveMode": 1, - "curveTo": "{1, 0.16791291024176927}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0.16791291024176927}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.96864484551850716, 0.0049008074281089711}", - "curveMode": 4, - "curveTo": "{1, 0.0070872332244901791}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{1, 0.0070872332244901791}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.47452257134117021, 0}", - "curveMode": 3, - "curveTo": "{0.86104313245640873, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.7358300922081894, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.29559061311890933, 0.23768916026328918}", - "curveMode": 4, - "curveTo": "{0.29559061311890933, 0.083801511560511244}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.29559061311890933, 0.23768916026328918}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.29559061311890933, 0.37028641604067547}", - "curveMode": 1, - "curveTo": "{0.29559061311890933, 0.37028641604067547}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.29559061311890933, 0.37028641604067547}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.37028641604067547}", - "curveMode": 1, - "curveTo": "{0, 0.37028641604067547}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0.37028641604067547}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.55011276448004953}", - "curveMode": 1, - "curveTo": "{0, 0.55011276448004953}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0.55011276448004953}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.29559061311890933, 0.55011276448004953}", - "curveMode": 1, - "curveTo": "{0.29559061311890933, 0.55011276448004953}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.29559061311890933, 0.55011276448004953}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.41857492461652751, 0.99944908956311651}", - "curveMode": 4, - "curveTo": "{0.29559061311890933, 1}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.29559061311890933, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.64910632347157293, 0.97130674807898676}", - "curveMode": 4, - "curveTo": "{0.53727658086789309, 0.98950400844729336}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.64910632347157293, 0.97130674807898676}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.64910632347157293, 0.55011276448004953}", - "curveMode": 1, - "curveTo": "{0.64910632347157293, 0.55011276448004953}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.64910632347157293, 0.55011276448004953}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 47, - "width": 25, - "x": 24, - "y": 14 - }, - "id": "85D93FCD-5A69-4DAF-AE90-351CD9B64554", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "7DEDDC31-9455-4677-8F90-529CB41EA4D5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 12.70833333333333, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Invite Friends Button", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 342, - "x": 36, - "y": 699 - }, - "id": "A6BFF201-765E-463B-99BC-F46EAFE2D98C", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "1832B4C7-3001-4C3E-AA08-D3D2E1D142C9", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 342, - "x": 0, - "y": 0 - }, - "id": "E9996286-0EBA-4D08-BEB5-B9A49B768BCD", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "DECF2495-AFB7-4E53-B934-927950CE85B5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Rectangle 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": true, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 30.5, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 30.5, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 30.5, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 30.5, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 100, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 342, - "x": 0, - "y": 0 - }, - "id": "C814E39E-06A4-4B97-A3C8-F86455BA308F", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "87845F2D-AC40-4B49-A94D-E07F37813671", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - }, - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.45, - "blue": 0.8901960784313725, - "green": 0.788235294117647, - "red": 0.09411764705882357 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 0.5, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Invite Friends", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Invite Friends", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 14, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "paragraphSpacing": 2.299999952316284, - "alignment": 0 - }, - "MSAttributedStringTextTransformAttribute": 1 - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {136, 14}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 138, - "x": 88, - "y": 21 - }, - "id": "C6E0225C-65AE-4FB2-B210-A17CC2682AD3", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "C0CD0577-47B5-45C9-B3F4-CDD7B4ED3CC5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0, 0}", - "gradientType": 0, - "to": "{1, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.9137254901960784, - "green": 0.3529411764705881, - "red": 0.3568627450980389 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.9411764705882353, - "green": 0.4549019607843137, - "red": 0.2784313725490197 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "MSAttributedStringTextTransformAttribute": 1, - "paragraphStyle": { - "_class": "paragraphStyle", - "paragraphSpacing": 2.299999952316284, - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "svg", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Spotify Copy", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 61, - "x": 0, - "y": 0 - }, - "id": "93AAA72A-7FA3-48F9-A329-6CAF4B38DF42", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "120EB29A-683F-4BC9-9554-3B680A035A54", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10.16666666666667, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Spotify", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "constraints": { - "scaleFactor": 1, - "model_version": 0.1, - "aspectRatio": { - "model_version": 0.1, - "enabled": 1, - "multiplier": 48, - "modelID": "constraint_4e4d9c72-56cb-4f9a-945e-5cb658c0a3a5", - "model_class": "ADModelConstraint", - "constant": 48 - }, - "modelID": "viewConstraints_4cbb1bd9-ccf1-4576-98f5-e7917524f2ad", - "model_class": "ADModelViewConstraints", - "automatic": 1 - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": false, - "pointRadiusBehaviour": 0, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22386215049526231, 0}", - "curveMode": 4, - "curveTo": "{0.49999701469367769, 0}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.49999701469367769, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77615576134267139}", - "curveMode": 2, - "curveTo": "{0, 0.22385617988261777}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.49999104408103312}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614382011738225, 1}", - "curveMode": 2, - "curveTo": "{0.22386215049526231, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.49999701469367769, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385617988261777}", - "curveMode": 2, - "curveTo": "{1, 0.77615576134267139}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.49999104408103312}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.49999701469367769, 0}", - "curveMode": 4, - "curveTo": "{0.77614382011738225, 0}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.49999701469367769, 0}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 61, - "width": 61, - "x": 0, - "y": 0 - }, - "id": "43CFDC5E-F7CC-4BAF-BC12-B9F65072D434", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "BE2C0514-12B3-4F05-99C6-B3846D2801FC", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10.16666666666667, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.8901960784313725, - "green": 0.788235294117647, - "red": 0.09411764705882357 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7058823529411764, - "green": 0.9019607843137255, - "red": 0 - } - }, - { - "_class": "gradientStop", - "position": 0.9736497471098265, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.8901960784313725, - "green": 0.788235294117647, - "red": 0.09411764705882357 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 29, - "width": 44, - "x": 9, - "y": 17 - }, - "id": "B25B2498-2C8B-4172-9BF9-A26EACA7E727", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "41EE6ED1-6230-4E6A-918A-93E21B4D71C9", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 12.70833333333333, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Fill 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 1.270833333333333, - "curveFrom": "{0, 0.4789936305732484}", - "curveMode": 1, - "curveTo": "{0, 0.4789936305732484}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0.4789936305732484}" - }, - { - "_class": "curvePoint", - "cornerRadius": 1.270833333333333, - "curveFrom": "{0.49999999999999994, 1}", - "curveMode": 1, - "curveTo": "{0.49999999999999994, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.49999999999999994, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 1.270833333333333, - "curveFrom": "{1, 0.5}", - "curveMode": 1, - "curveTo": "{1, 0.5}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 1.270833333333333, - "curveFrom": "{0.49999999999999994, 0}", - "curveMode": 1, - "curveTo": "{0.49999999999999994, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.49999999999999994, 0}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 18, - "width": 44, - "x": 0, - "y": 0 - }, - "id": "7B094F2E-5C0E-4BDD-909A-9826BE39B7C0", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "90C12C14-8A60-462F-BD67-79DB53E191E7", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 12.70833333333333, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Fill 6", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.86054967213375011}", - "curveMode": 4, - "curveTo": "{0, 0.68853500150834324}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0, 0.68853500150834324}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77620899273245914, 1}", - "curveMode": 2, - "curveTo": "{0.22385892820756628, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.49999999999999989, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.68853500150834324}", - "curveMode": 4, - "curveTo": "{1, 0.86054967213375011}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{1, 0.68853500150834324}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.014813521108870532}", - "curveMode": 1, - "curveTo": "{1, 0.014813521108870532}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0.014813521108870532}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.49935475106975474, 0.38924789228839557}", - "curveMode": 1, - "curveTo": "{0.49935475106975474, 0.38924789228839557}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.49935475106975474, 0.38924789228839557}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 14, - "width": 26, - "x": 9, - "y": 15 - }, - "id": "7E6BAF73-2733-475D-9715-32721DD88B45", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "58D910A6-BD77-49F6-B533-DD9FAA672157", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 12.70833333333333, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 82, - "width": 85, - "x": 166, - "y": 44 - }, - "id": "66464E42-E480-4BF4-B3B3-43919A5DA6CF", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/d4e1ba0e5ea98dbe54bcfaebd1aefde4182cbcb9.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "10C18FD1-2A0A-4720-98EC-C93BDB18AC4D", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "normal", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.bohemiancoding.sketchtool.detach": { - "symbolInstance": { - "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 93, - "width": 375, - "x": 0, - "y": 724 - } - }, - "symbolMaster": { - "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", - "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" - } - }, - "com.sketch.detach": { - "symbolInstance": { - "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 93, - "width": 375, - "x": 0, - "y": 724 - } - }, - "symbolMaster": { - "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", - "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 322, - "x": 46, - "y": 816 - }, - "id": "BBB88857-820C-4AF2-8D41-3040470884C3", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E48C7801-74D7-4DF2-93B9-FE2DCD3DCD08", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "homeicon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 26, - "width": 28, - "x": 0, - "y": 19 - }, - "id": "CA563D31-03EB-402B-B97F-26BE27CD703C", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/724477925ebd536321fbadee7e227cfd057eb0f5.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E267727C-05B9-4253-B17D-D4AB347AF316", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7294117647058823, - "green": 0.6235294117647059, - "red": 0.5843137254901961 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "BBD21E46-AD9D-4372-AE85-42558046DA42", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "stats", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "BBD21E46-AD9D-4372-AE85-42558046DA42", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 26, - "width": 26, - "x": 222, - "y": 21 - }, - "id": "14151DE3-E3BA-467F-AAF8-F55CC02C1B70", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/791dd23b4cf727cd2ad676896de2196a29d57e2d.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "8DFFC13B-ACB5-49BF-A628-6BBAB8DF0797", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "plus-icon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 61, - "width": 54, - "x": 130, - "y": 0 - }, - "id": "786574C6-2F8C-49B7-936B-B20B9E90F7E7", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/c4eea6263c1c1732dcb7a96694a80dd390a1ff7d.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "5BAB6305-36A1-4EFE-9EE8-0FC60C1E57D8", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "22155B2E-9044-4DCD-A0D1-C5656655323A", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "not published", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "22155B2E-9044-4DCD-A0D1-C5656655323A", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 25, - "width": 25, - "x": 74, - "y": 20 - }, - "id": "86F1F154-0A1B-40FE-823F-BCF2CF3AA063", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5c0161e4cd699ec44a35f72b3b4b529f464c6f94.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "46C2AD45-50F0-4AB4-AC4D-CECEF1D7763C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "learn", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 23, - "width": 26, - "x": 296, - "y": 25 - }, - "id": "A8D88F06-7DC0-4CC6-8A19-1DD50BCEED21", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5ce1816426a25e74eb636fbaa1e06a6627b7d7ee.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "0093DCA4-F75F-4D01-B1E2-99E27AE276C1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "CLASS_NAME": null, - "type": "artboard", - "includeInCloudUpload": true, - "includeBackgroundColorInExport": true, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "layout": null, - "grid": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 896, - "width": 414, - "x": 1165, - "y": -295 - }, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "id": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", - "hasBackgroundColor": false, - "isFlowHome": false, - "resizesContent": false, - "presetDictionary": { - "name": "iPhone 11", - "offersLandscapeVariant": 1, - "height": 896, - "allowResizedMatching": 1, - "width": 414 - }, - "visible": true, - "style": { - "_class": "style", - "do_objectID": "392B71E3-523A-43F7-8AAA-1ECDAD54DF46", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "artboard" - }, - "azure_blob_uri": "/B8F978E3-16B6-4278-B836-B67E3F123C68.png" - }, - { - "pbdfType": "screen", - "id": "24a06315-fbdb-489c-a4e5-5359ca2a4217", - "name": "person/4", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "LearningOverviewAlt", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "header", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.bohemiancoding.sketchtool.detach": { - "symbolInstance": { - "do_objectID": "941D602A-D496-4CC2-8F15-A1E5FFB77A4A", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 414, - "x": 0, - "y": 0 - } - }, - "symbolMaster": { - "do_objectID": "ADF19C17-3F52-4FE3-B207-2A6E6AC2DB95", - "symbolID": "65B0D541-BC41-4E38-81E3-41E0946BC70B" - } - }, - "com.sketch.detach": { - "symbolInstance": { - "do_objectID": "941D602A-D496-4CC2-8F15-A1E5FFB77A4A", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 414, - "x": 0, - "y": 0 - } - }, - "symbolMaster": { - "do_objectID": "ADF19C17-3F52-4FE3-B207-2A6E6AC2DB95", - "symbolID": "65B0D541-BC41-4E38-81E3-41E0946BC70B" - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 414, - "x": 0, - "y": 0 - }, - "id": "94F89071-B4F6-410D-887D-AF082F7F2C80", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4BAE7A62-A55F-4322-98D2-0CB40395AA2C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 0, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 95, - "width": 414, - "x": 0, - "y": 0 - }, - "id": "5DC9BD8F-C5ED-4866-A4D9-B27BF479B241", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "356D8E5E-352A-48F0-AB1E-D8A1774C9BCC", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.2078431372549019 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.207843137254902 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "userScore", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 25, - "width": 78, - "x": 168.912, - "y": 51 - }, - "id": "7D00B6BE-0E2D-4070-A030-361C8467375D", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F36367EC-10F0-4B0B-AFF1-135E96329ACE", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "285", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "285", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 3, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 21 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 5}, {38, 16}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 25, - "width": 40, - "x": 0, - "y": 0 - }, - "id": "6E819171-9A2D-4637-91E2-E78320280444", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "006F588A-0F39-497A-8702-4C700E08FCFB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Bold", - "size": 21 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle" - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "starIcon", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 22, - "width": 24.28799999999999, - "x": 52.99199999999998, - "y": 2 - }, - "id": "0053C932-F835-458F-B0E3-3FD7DFF564BA", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/7dc57eea260f608d09f997083c71f337eda203ca.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "CB5342B7-5060-4079-B9C9-01BF7CBACD67", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "bellIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 29.2258064516129, - "width": 27.77806451612903, - "x": 18.76799999999998, - "y": 48.77419354838709 - }, - "id": "26DB7CAC-F3BE-4511-ACFF-F47617244758", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/1ab87eea21615010a2576c5a46416a88641231ec.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "988FD171-E4E6-4587-B377-FAF3DC822820", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "profileIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 34, - "width": 37.536, - "x": 359.904, - "y": 48 - }, - "id": "76846784-DD7F-41D6-B842-655F40CC327D", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/e743cc27bf064b8b45e6c8d1c40d8200bf4f7732.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6B81B647-BA5A-4554-AB36-4CE64E56074C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Categories", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Categories", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 10, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{0, 3}, {87, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 88, - "x": 23, - "y": 160 - }, - "id": "CCA8F746-FCF4-4A56-ABC7-407A352099E3", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "7794BFC0-9651-48EB-888C-3D5E7C73AC8D", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "1. Bars / 2. Top Bar / 2. Large / Heading + Search", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 40, - "width": 126, - "x": 22, - "y": 113 - }, - "id": "1E78D0AA-8AAA-4388-AD04-59D2AD9E874E", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "1E08EB87-015B-4E84-9B22-067ED7AA7E06", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "🅰️ Heading", - "nameIsFixed": true, - "resizingConstraint": 41, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": "4475D330-67E5-4F54-AA9A-872C355EA16D", - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.invisionlabs.duplicate": { - "type-duplicate": { - "title": "Advertising", - "action": "article", - "options": { - "section": "advertising", - "type": "title" - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Explore", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 7, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 32 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.3618807196617126, - "green": 0.1713331937789917, - "red": 0.01447581406682729 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "maximumLineHeight": 40, - "minimumLineHeight": 40, - "alignment": 0 - }, - "kerning": 0.6240000000000001 - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{2, 7}, {122, 30}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 40, - "width": 126, - "x": 0, - "y": 0 - }, - "id": "BA34833A-44CE-40E8-9355-C9271E255038", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6D5E548A-28B5-4C96-AE1C-D9ED3ACABCFB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 32 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.3618807196617126, - "green": 0.1713331937789917, - "red": 0.01447581406682729 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "maximumLineHeight": 40, - "minimumLineHeight": 40, - "alignment": 0 - }, - "kerning": 0.6240000000000001 - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 155, - "width": 105, - "x": 22, - "y": 198 - }, - "id": "3BB30F81-45EF-4A63-97F8-0845A49DB6B3", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B351B8F7-FDFF-4E4E-A2CC-E3C89C1D2111", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 155, - "width": 105, - "x": 0, - "y": 0 - }, - "id": "D6902730-8775-4EC7-94F0-7E454B33AAAE", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "461E8C70-9CD6-402F-A5F6-E3A36D081DEB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 8, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 155, - "width": 105, - "x": 0, - "y": 0 - }, - "id": "5FDDFB6C-067B-4B27-B14F-D157469D2773", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "246896A3-5690-46F5-A399-6A2274561287", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.2078431372549019 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.207843137254902 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Careers", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Careers", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 7, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 4}, {59, 13}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 61, - "x": 22, - "y": 129 - }, - "id": "AA8CE149-92C3-4A7A-92F8-F6C3F06F5601", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "CA8F670B-99F1-4D7C-907B-F29C73F8894F", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "simplePaperIcon", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 74, - "width": 73, - "x": 16, - "y": 28 - }, - "id": "556125DB-7C28-42D8-B4E1-C1FB5BFC479B", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/fd293ef7fd2f13ffb9962408e16bb189809d7d33.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "98F39059-25E0-4B98-BCD2-2854F2AEF17B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 2 Copy", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 155, - "width": 105, - "x": 155, - "y": 198 - }, - "id": "8B925AFE-DBB6-4DE6-B807-89B1D9C0DD70", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "743111D8-51FE-4561-A2B1-C85A7D91EFFC", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 155, - "width": 105, - "x": 0, - "y": 0 - }, - "id": "30604AF7-A9DF-4A98-9F19-86B9B15BFA0C", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "0EE05200-FDBC-4F15-9EEE-B3D5F888897C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 8, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 155, - "width": 105, - "x": 0, - "y": 0 - }, - "id": "CD086050-0F04-4404-8021-FA787172B16A", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "0F081EEA-B180-426B-9FE7-C6D9F4B3FBBB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.2078431372549019 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.207843137254902 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Majors", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Majors", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 6, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {51, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 53, - "x": 27, - "y": 129 - }, - "id": "68EC2E9C-9285-494E-BB94-1B8C31978B2F", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "BEEB30F6-28E4-4113-987D-8459D65ED1C1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "simplePaperIcon", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 74, - "width": 73, - "x": 16, - "y": 28 - }, - "id": "9B3D1988-167F-47DA-9885-DD0F0AD2321D", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/fd293ef7fd2f13ffb9962408e16bb189809d7d33.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "1C319D1E-567D-4B9A-B8FB-F8C6CB2F9A8F", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 2 Copy 2", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 155, - "width": 105, - "x": 288, - "y": 198 - }, - "id": "7023E57E-5505-4B7E-8E77-766F979B5A53", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "25D09D8C-02AD-4EA0-B1D0-A96F0D19B5BD", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 155, - "width": 105, - "x": 0, - "y": 0 - }, - "id": "4B552FC8-0C31-4DE8-91A6-57EA9CDC9776", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "5558C7E0-9E63-4057-87AA-960C9F3CAEF9", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 8, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 155, - "width": 105, - "x": 0, - "y": 0 - }, - "id": "9EEA394B-09DE-4B73-90B8-19554FD98998", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "660D914F-4351-4C98-8C65-565079F5D0BB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.984313725490196, - "green": 0.596078431372549, - "red": 0.2078431372549019 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{1, 1}", - "gradientType": 0, - "to": "{0, 0}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.9115715579710145, - "green": 0.8498216172586106, - "red": 0.7880716765462067 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7647058823529411, - "green": 0.3372549019607842, - "red": 0.2117647058823529 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Colleges", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Colleges", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 8, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 4}, {65, 16}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 67, - "x": 19, - "y": 129 - }, - "id": "3A5EF981-4C73-4B5C-9FFA-3315C5C94466", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "AE2508FA-F195-40A8-B287-BB5D904F444C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "simplePaperIcon", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 74, - "width": 73, - "x": 16, - "y": 28 - }, - "id": "9FB103B3-C1A8-4B8C-8EEC-927880C7CB59", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/fd293ef7fd2f13ffb9962408e16bb189809d7d33.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "519ABD12-BB51-42DF-8162-9A26D08501A7", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Continue Learning", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Continue Learning", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 17, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{0, 3}, {148, 17}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 149, - "x": 23, - "y": 371 - }, - "id": "E1153CD7-8B2B-4059-8C78-F62760268383", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "085CC7D2-A9A1-430C-BB36-C3872168B06E", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "View All", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "View All", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 8, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 14 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.9490196078431372, - "green": 0.5568627450980396, - "red": 0.211764705882353 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{0, 2}, {52, 12}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 16, - "width": 53, - "x": 340, - "y": 375 - }, - "id": "99B6F452-E659-4BFE-9686-B11E3E4EDC1E", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "068F3D4D-CF71-432E-9B29-B280BAA8363E", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 14 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.9490196078431372, - "green": 0.5568627450980396, - "red": 0.211764705882353 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Lesson Big Card", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 31, - "y": 419 - }, - "id": "9DB70E49-FE27-4056-92F2-EC99F0194E73", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B3FB6F58-DCD4-4A0A-B9E2-E012F9AAACE1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "6E30FE6F-1084-4C92-B3B5-1D65881E5435", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "05F02B59-BAAA-4539-90ED-3DBC6925F8F9", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 8, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "4D4F8F46-0F68-4C04-8693-EBAA0C4A47AF", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "A36E5F42-2A53-49FB-AF4E-292C528EDEB5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7725490196078432, - "green": 0.2117647058823529, - "red": 0.4980392156862745 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{-0.011826262394689041, 0.081614891851427465}", - "gradientType": 0, - "to": "{0.92197160979761905, 0.86807351602486948}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7725490196078432, - "green": 0.211764705882353, - "red": 0.4978553921568629 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.6625905797101449, - "green": 0.3741338919312257, - "red": 0.5905552038449001 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Fundamentals of Algo", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Fundamentals\nof Algorithms", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 26, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {120, 37}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 40, - "width": 121, - "x": 22, - "y": 14 - }, - "id": "DF4BD58E-35FB-408A-9535-F39342546684", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E0231EF1-6D28-4FE4-B834-AEB4C87A8D68", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "paperIcon", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 97, - "width": 97, - "x": 34, - "y": 74 - }, - "id": "22F842A2-E6E1-4AA0-AA65-618A000F87B3", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/83c10f3fe733b88aca886ce5f9ba40355d502171.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "1FC55A62-6D34-4663-9199-549A2C33958B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 5", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 218, - "y": 419 - }, - "id": "BE00E55E-048D-4CFB-8DFD-C45A55AEA88D", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "74C27C5B-059C-4037-8BD0-1F9FF646A7E4", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Lesson Big Card Copy", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "6F732523-C652-42A1-A416-2718BCB64AEA", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4E4D066F-3B75-4453-9B69-939313F030A1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "415D8464-E46A-4B69-B567-6E9302F915EE", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "100391D6-1F8C-4342-8436-AF0D380ACEF1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 8, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "B6054139-473E-4021-B65F-D2A93E28C0F2", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "042E3055-9E33-449F-92D0-0A960B8229BA", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.85, - "blue": 0, - "green": 0, - "red": 0 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{-0.011826262394689041, 0.081614891851427465}", - "gradientType": 0, - "to": "{0.92197160979761905, 0.86807351602486948}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7725490196078432, - "green": 0.211764705882353, - "red": 0.4978553921568629 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.6625905797101449, - "green": 0.3741338919312257, - "red": 0.5905552038449001 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Finance", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Finance", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 7, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 2}, {65, 15}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 67, - "x": 49, - "y": 14 - }, - "id": "D1379E19-80E5-4D48-9B86-ED8A4547E852", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6EC85059-B120-4775-B0C9-BA7DBA01872F", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "cashIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 93, - "width": 132, - "x": 16, - "y": 74 - }, - "id": "089F3BA8-2C99-48B6-83E3-DA903D8D9973", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5ba1a8495a66eacb0d83c6546dc05ec1cc687e67.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "04BD411A-5419-4863-8F71-9784E5A52487", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Lessons", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Lessons", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 7, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 4}, {64, 13}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 66, - "x": 36, - "y": 626 - }, - "id": "91C8C1DE-74EB-4F19-BC19-C02F5A3F65F5", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B374B44E-727F-47EF-BFAD-15E5260D2354", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Semibold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 0.04472257653061224, - "green": 0.04472257653061224, - "red": 0.04472257653061224 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Lesson Big Card", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 31, - "y": 664 - }, - "id": "6182EE5C-B95D-4224-A85E-46BE5E126B06", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "C16F2315-8D16-4C61-BADA-2975863F4680", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "210B3FA3-DEBF-4E9C-BEFA-531E3EB4BE18", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E87DEB8D-C8CA-48F2-8396-A9033FD46E32", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 8, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "A1CDA745-DA2D-4D2F-AAB5-4A1C14C0EFFC", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "204D36A5-9F12-4648-B5D7-763992C40C37", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7725490196078432, - "green": 0.2117647058823529, - "red": 0.4980392156862745 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{-0.011826262394689041, 0.081614891851427465}", - "gradientType": 0, - "to": "{0.92197160979761905, 0.86807351602486948}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7725490196078432, - "green": 0.211764705882353, - "red": 0.4978553921568629 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.6625905797101449, - "green": 0.3741338919312257, - "red": 0.5905552038449001 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Fundamentals of Algo", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Fundamentals\nof Algorithms", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 26, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 3}, {120, 37}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 40, - "width": 121, - "x": 22, - "y": 14 - }, - "id": "861A0370-C107-4A5F-AD75-B4A574FA5F82", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B2099770-8646-43D4-91FF-2BDA6DD33C6E", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "paperIcon", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 97, - "width": 97, - "x": 34, - "y": 74 - }, - "id": "51675CD4-5EC9-49FB-8B8E-F60F22743F0B", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/83c10f3fe733b88aca886ce5f9ba40355d502171.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "CD446D7A-3119-470F-996A-1661A8E58397", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 5", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 218, - "y": 664 - }, - "id": "503CC118-F6CD-45B9-8F3E-A8CE21F5857B", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "49CE6C0A-59E1-4924-B9CE-FD13BB79D1DB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Lesson Big Card Copy", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "98061207-A8DB-446F-91DC-C115C01AD741", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "93C7447F-3FFB-47F7-B322-F4F952251B3A", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 4", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "947F75F5-F92E-4428-9ABB-93D8D30DE80F", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "FCE1128D-D7FD-4283-917B-5C5D366D077D", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Background", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 8, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 8, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 200, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "385B396A-DA82-4C16-B355-AAB244BF7CF4", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B1FFD055-C4B2-4803-B391-351493E0B147", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.85, - "blue": 0, - "green": 0, - "red": 0 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{-0.011826262394689041, 0.081614891851427465}", - "gradientType": 0, - "to": "{0.92197160979761905, 0.86807351602486948}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7725490196078432, - "green": 0.211764705882353, - "red": 0.4978553921568629 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.6625905797101449, - "green": 0.3741338919312257, - "red": 0.5905552038449001 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Finance", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Finance", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 7, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 0, - "glyphBounds": "{{1, 2}, {65, 15}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 20, - "width": 67, - "x": 49, - "y": 14 - }, - "id": "4E39823B-DF29-4C6C-B7E3-7183B3B446AC", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B81E06BD-EF4D-436A-BE3D-9BE0EC2DEB85", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFProText-Bold", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "textStyleVerticalAlignmentKey": 0, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 2 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "cashIcon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 93, - "width": 132, - "x": 16, - "y": 74 - }, - "id": "A64B057B-A87C-44A1-A263-AE547B29543A", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5ba1a8495a66eacb0d83c6546dc05ec1cc687e67.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "EF6365AE-8330-4433-9A3C-59D9D18ED42E", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - } - ], - "pbdfType": "group" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 1, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@2x", - "namingScheme": 0, - "scale": 2, - "visibleScaleType": 0 - }, - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "@3x", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "normal", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.bohemiancoding.sketchtool.detach": { - "symbolInstance": { - "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 93, - "width": 375, - "x": 0, - "y": 724 - } - }, - "symbolMaster": { - "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", - "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" - } - }, - "com.sketch.detach": { - "symbolInstance": { - "do_objectID": "A5EED0AC-A48F-4423-B817-A7D07043D2BD", - "frame": { - "_class": "rect", - "constrainProportions": false, - "height": 93, - "width": 375, - "x": 0, - "y": 724 - } - }, - "symbolMaster": { - "do_objectID": "99293D0E-FBA8-4F53-BE11-4DFD8B6378B9", - "symbolID": "592CA564-E8E1-4E0E-B8DF-6B64AA893D55" - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 61, - "width": 322, - "x": 47, - "y": 818 - }, - "id": "4465305C-8C87-48DC-B662-AF658EB7713F", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "9E862139-C397-4E51-956B-47F67F411ADD", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "homeicon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "3A06138A-40E2-40D7-90CB-56BAD609D9CE", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 26, - "width": 28, - "x": 0, - "y": 19 - }, - "id": "144F29D7-8F19-4AAF-8CBF-4E123EC8176C", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/724477925ebd536321fbadee7e227cfd057eb0f5.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "603BEA0F-3C21-42DC-A944-66DA717E6A5D", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7294117647058823, - "green": 0.6235294117647059, - "red": 0.5843137254901961 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "BBD21E46-AD9D-4372-AE85-42558046DA42", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "stats", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "BBD21E46-AD9D-4372-AE85-42558046DA42", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 26, - "width": 26, - "x": 222, - "y": 21 - }, - "id": "3CF02E70-7943-4864-A26D-6E77EE3904BE", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/791dd23b4cf727cd2ad676896de2196a29d57e2d.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E0029D22-7647-4AF3-8535-4C5859A0537F", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "plus-icon", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 59.89090909090909, - "width": 52.56, - "x": 130.72, - "y": 0.7393939393939394 - }, - "id": "1BE4D5A9-58A4-4813-8FE0-E6D556B7476F", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/a760f6e1fcbe5bc9ee36e6c2a56110bbac66b4ed.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "7EB73318-7DFE-45F8-AE16-7B65D73AB592", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": { - "_class": "MSImmutableFlowConnection", - "destinationArtboardID": "22155B2E-9044-4DCD-A0D1-C5656655323A", - "maintainScrollPosition": false, - "animationType": 0 - }, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "not published", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": "22155B2E-9044-4DCD-A0D1-C5656655323A", - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 25, - "width": 25, - "x": 74, - "y": 22 - }, - "id": "0B199A09-DD5D-46B8-9780-8862CD2CAE4D", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5c0161e4cd699ec44a35f72b3b4b529f464c6f94.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "05D5063F-57D2-4417-8EB8-1D694968EB96", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "learn", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 72, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 23, - "width": 26, - "x": 296, - "y": 25 - }, - "id": "92D28B96-2E46-4AE8-9195-566E1F8BE291", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/5ce1816426a25e74eb636fbaa1e06a6627b7d7ee.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "4FA8E9BA-59DC-48D4-96FF-D177877339A1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "CLASS_NAME": null, - "type": "artboard", - "includeInCloudUpload": true, - "includeBackgroundColorInExport": true, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "layout": null, - "grid": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 896, - "width": 414, - "x": 176, - "y": -295 - }, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "id": "C1AA2B99-E400-4E44-9000-E19A547ED3B9", - "hasBackgroundColor": false, - "isFlowHome": false, - "resizesContent": false, - "presetDictionary": { - "height": 896, - "offersLandscapeVariant": 1, - "width": 414, - "allowResizedMatching": 1, - "name": "iPhone 11" - }, - "visible": true, - "style": { - "_class": "style", - "do_objectID": "C17C3CAE-EFDC-4347-B3C1-644A4A629510", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "artboard" - }, - "azure_blob_uri": "/24A06315-FBDB-489C-A4E5-5359CA2A4217.png" - }, - { - "id": "c756078b-9e00-45cf-8978-050e04f39e68", - "name": "person/frame", - "convert": true, - "azure_blob_uri": "/C756078B-9E00-45CF-8978-050E04F39E68.png", - "type": "symbolMaster" - }, - { - "id": "277a3d19-a01b-4e11-8f57-7c6d9b49749c", - "name": "person/1", - "convert": true, - "azure_blob_uri": "/277A3D19-A01B-4E11-8F57-7C6D9B49749C.png", - "type": "symbolMaster" - }, - { - "id": "ac76fba2-f9ca-4dee-94ed-03918f4ce652", - "name": "person/5", - "convert": true, - "azure_blob_uri": "/AC76FBA2-F9CA-4DEE-94ED-03918F4CE652.png", - "type": "symbolMaster" - }, - { - "id": "14464801-56ae-4b2e-888b-b7c56bb513dc", - "name": "person/12", - "convert": true, - "azure_blob_uri": "/14464801-56AE-4B2E-888B-B7C56BB513DC.png", - "type": "symbolMaster" - }, - { - "id": "2c9ab975-28fc-40c1-ad16-a32bba023e53", - "name": "person/withframe", - "convert": true, - "azure_blob_uri": "/2C9AB975-28FC-40C1-AD16-A32BBA023E53.png", - "type": "symbolMaster" - }, - { - "id": "d377e55e-2dc6-446a-ac51-4c913a2b5692", - "name": "someElement/green", - "convert": true, - "azure_blob_uri": "/D377E55E-2DC6-446A-AC51-4C913A2B5692.png", - "type": "symbolMaster" - }, - { - "id": "d5f9ba19-3b15-490c-b31b-24aa26d8b77b", - "name": "someElement/default", - "convert": true, - "azure_blob_uri": "/D5F9BA19-3B15-490C-B31B-24AA26D8B77B.png", - "type": "symbolMaster" - } - ] - }, - { - "pbdfType": "design_page", - "id": "e6289062-5385-4b33-895f-3903b00ac1b5", - "name": "Index Screens", - "convert": false, - "screens": [ - { - "pbdfType": "symbol_master", - "id": "22155b2e-9044-4dcd-a0d1-c5656655323a", - "name": "Majors Overview", - "convert": false, - "type": "artboard", - "designNode": { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "SmallMajorCard", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "EF5FB7A4-64EB-4CA0-BBE9-834BF8C8AC46", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [ - { - "overrideName": "44671E81-67A4-4092-BA3A-85BD386E3A0D_stringValue", - "canOverride": true - } - ], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 965, - "y": 0 - }, - "id": "A1CA9316-82B5-4270-B143-97575F0EC1D0", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "7B52A67B-CC26-49DC-BA57-A44E36BB3DD5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group Copy 3", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "5902329C-3987-4B23-8498-975E7C0C1C1A", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "22D3F25F-BE59-41C5-ADBF-CF9EB43BC581", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 10, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 10, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 80, - "width": 165, - "x": 0, - "y": 0 - }, - "id": "6B9C49AF-B62C-4301-AC20-7FA7EAD3CCCA", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "234CE166-E055-486A-9081-9F910352A40D", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7686274509803921, - "green": 0.3411764705882353, - "red": 0.2117647058823529 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.10430849801947592, 0.14482966241182565}", - "gradientType": 0, - "to": "{0.87787832789057207, 0.86568038915591661}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.7686274509803922, - "green": 0.3411764705882352, - "red": 0.2117647058823529 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.9764705882352941, - "green": 0.5843137254901962, - "red": 0.2078431372549021 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Information Systems", - "nameIsFixed": false, - "resizingConstraint": 47, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "isAutoWidth": 1 - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "attributedString": { - "_class": "attributedString", - "string": "Information Systems", - "attributes": [ - { - "_class": "stringAttribute", - "location": 0, - "length": 19, - "attributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - } - } - ] - }, - "automaticallyDrawOnUnderlyingPath": false, - "dontSynchroniseWithSymbol": false, - "lineSpacingBehaviour": 2, - "textBehaviour": 1, - "glyphBounds": "{{0, 3}, {92, 37}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 40, - "width": 117, - "x": 12, - "y": 13 - }, - "id": "44671E81-67A4-4092-BA3A-85BD386E3A0D", - "type": "text", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6323C2AB-75FD-4223-8817-F8AA75985F86", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": { - "encodedAttributes": { - "MSAttributedStringFontAttribute": { - "_class": "fontDescriptor", - "attributes": { - "name": "SFCompactText-Regular", - "size": 17 - } - }, - "MSAttributedStringColorAttribute": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "paragraphStyle": { - "_class": "paragraphStyle", - "alignment": 0 - } - }, - "fontFamily": null, - "fontSize": null, - "fontWeight": null, - "weight": null - } - }, - "pbdfType": "text" - } - ], - "pbdfType": "group" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/22155B2E-9044-4DCD-A0D1-C5656655323A.png" - }, - { - "pbdfType": "symbol_master", - "id": "36eb4ce8-41dd-4ede-a4bd-ed88d043d9f1", - "name": "Landing Page", - "convert": false, - "type": "artboard", - "designNode": { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "icons/tabbar/home", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "7C0DA89B-7956-40D4-AB6D-1A0DB5D53C20", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [ - { - "overrideName": "B12B62C2-D7E3-452E-963E-A24216DD0942_layerStyle", - "canOverride": true - } - ], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 32, - "width": 32, - "x": 100, - "y": 264 - }, - "id": "7ABB7146-7156-4FA4-8E2D-F816FD51ED27", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "00BDA43A-F7B4-47FE-BB00-50DF3342D4D1", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Oval", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "constraints": { - "scaleFactor": 1, - "model_version": 0.1, - "aspectRatio": { - "model_class": "ADModelConstraint", - "enabled": 1, - "multiplier": 26, - "constant": 26, - "model_version": 0.1, - "modelID": "constraint_b463a532-3d93-4801-baa5-bb66b2d2925f" - }, - "modelID": "viewConstraints_bf976398-3916-4b68-89f2-37e4bd211879", - "model_class": "ADModelViewConstraints", - "automatic": 1 - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614237490000004, 1}", - "curveMode": 2, - "curveTo": "{0.22385762510000001, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385762510000001}", - "curveMode": 2, - "curveTo": "{1, 0.77614237490000004}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22385762510000001, 0}", - "curveMode": 2, - "curveTo": "{0.77614237490000004, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77614237490000004}", - "curveMode": 2, - "curveTo": "{0, 0.22385762510000001}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 24, - "width": 24, - "x": 4, - "y": 4 - }, - "id": "0750E655-B2B6-4BF4-BB79-FE199ADCD442", - "type": "oval", - "visible": false, - "style": { - "_class": "style", - "do_objectID": "F2159235-3DCD-4F24-817E-8BB87663592D", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 0.3065243675595238 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "oval" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [ - { - "_class": "exportFormat", - "absoluteSize": 0, - "fileFormat": "png", - "name": "", - "namingScheme": 0, - "scale": 3, - "visibleScaleType": 0 - } - ] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Shape", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": "10B8A524-8E34-4194-AF07-EFBC51AE2411", - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "windingRule": 1, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 21, - "width": 23.33333333333334, - "x": 4, - "y": 6 - }, - "id": "B12B62C2-D7E3-452E-963E-A24216DD0942", - "type": "shapeGroup", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "A276C6C9-ECE5-4AB0-9828-BAF0748FD5BA", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.65, - "green": 0.56615, - "red": 0.533 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Path", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.49450108835277012, 7.4490142024652428e-06}", - "curveMode": 2, - "curveTo": "{0.5055762181935034, 2.157848065534318e-05}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.48424479999999998, 0.0074462875000000095}", - "curveMode": 4, - "curveTo": "{0.48908856784325078, 0.0025655367448264577}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.48424479999999998, 0.0074462875000000095}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.017903645999999999, 0.44458006250000004}", - "curveMode": 1, - "curveTo": "{0.017903645999999999, 0.44458006250000004}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.017903645999999999, 0.44458006250000004}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.0069166546011208436, 0.45545982713662758}", - "curveMode": 4, - "curveTo": "{0.017903645999999999, 0.44470212499999995}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.017903645999999999, 0.44470212499999995}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{2.0452959175910712e-05, 0.5232403048716201}", - "curveMode": 2, - "curveTo": "{2.0452959175910712e-05, 0.4767596951283799}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.017903646000000006, 0.55529787499999994}", - "curveMode": 4, - "curveTo": "{0.0069166546011208436, 0.54454017286337242}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.017903646000000006, 0.55529787499999994}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.017903645999999999, 0.55541993749999996}", - "curveMode": 1, - "curveTo": "{0.017903645999999999, 0.55541993749999996}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.017903645999999999, 0.55541993749999996}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.48893954673107093, 0.9973342343594731}", - "curveMode": 4, - "curveTo": "{0.48404946666666665, 0.99230956250000002}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.48404946666666665, 0.99230956250000002}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.50549891278150572, 0.99999254329967457}", - "curveMode": 4, - "curveTo": "{0.49442378151854688, 0.99997841960312694}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.51575519999999997, 0.99255368750000006}", - "curveMode": 4, - "curveTo": "{0.51091143335753031, 0.99743444694915162}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.51575519999999997, 0.99255368750000006}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.98187957193968611, 0.55558375807325056}", - "curveMode": 4, - "curveTo": "{0.98177083333333337, 0.5556640625}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.98177083333333337, 0.5556640625}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.98209636666666666, 0.55541993749999996}", - "curveMode": 4, - "curveTo": "{0.98198808455141251, 0.55550238194790424}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.98209636666666666, 0.55541993749999996}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.99308335315753915, 0.54454016641966496}", - "curveMode": 4, - "curveTo": "{0.98209636666666666, 0.55529787500000005}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.98209636666666666, 0.55529787500000005}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.99997954950709833, 0.47675970029528714}", - "curveMode": 2, - "curveTo": "{0.99997954950709833, 0.52324029970471286}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.98209636666666666, 0.44470212500000006}", - "curveMode": 4, - "curveTo": "{0.99308335315753915, 0.45545983358033504}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.98209636666666666, 0.44470212500000006}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.98209636666666666, 0.44458006250000004}", - "curveMode": 1, - "curveTo": "{0.98209636666666666, 0.44458006250000004}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.98209636666666666, 0.44458006250000004}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.51106045296356506, 0.0026657615669901102}", - "curveMode": 4, - "curveTo": "{0.51595053333333341, 0.0076904312499999905}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.51595053333333341, 0.0076904312499999905}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 12.44444444444445, - "width": 23.33333333333334, - "x": 0, - "y": 0 - }, - "id": "9907F8CC-2BCC-489A-8C25-B86A4316EC2B", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6F9ACE86-C918-484D-90F1-DEF37A6C6CC5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - }, - { - "booleanOperation": 1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Rectangle", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 63, - "sharedStyleID": "10B8A524-8E34-4194-AF07-EFBC51AE2411", - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0.9, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0.9, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0.9, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0.9, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 0.9, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 9, - "width": 1.8, - "x": 15.70901570946376, - "y": 2.757221642229653 - }, - "id": "ABD43AA3-8BE9-4909-A6B9-040C6C19568A", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "524FEE05-5452-4E6E-81C0-DA9CFDF4B01E", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.65, - "green": 0.5785, - "red": 0.5525 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Path", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.75, 0}", - "curveMode": 1, - "curveTo": "{0.75, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.75, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.25, 0.063912122365638188}", - "curveMode": 1, - "curveTo": "{0.25, 0.063912122365638188}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0.25, 0.063912122365638188}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.10109149999999989, 0.65638369617097347}", - "curveMode": 4, - "curveTo": "{0.25, 0.63425290947154644}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.25, 0.63425290947154644}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.8149744057514775}", - "curveMode": 3, - "curveTo": "{0, 0.69712390336384844}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.7443515105374473}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.5, 1}", - "curveMode": 2, - "curveTo": "{0.5, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.69712390336384844}", - "curveMode": 3, - "curveTo": "{1, 0.8149744057514775}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.7443515105374473}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.75, 0.63425290947154644}", - "curveMode": 4, - "curveTo": "{0.89890850000000011, 0.65638369617097347}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.75, 0.63425290947154644}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 12.16948755555555, - "width": 3.111111111111111, - "x": 20.22222222222222, - "y": 8.830512444444446 - }, - "id": "3EB1B5AD-63BD-45A2-A5BC-DC0DB94FEA88", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "87080C3A-47BE-4994-8866-C69DB8590422", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - }, - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Path", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": true, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.7552587665785131}", - "curveMode": 4, - "curveTo": "{0, 0.45345861227894851}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0, 0.45345861227894851}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77616666666666667, 1}", - "curveMode": 2, - "curveTo": "{0.22383333333333333, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.45345861227894851}", - "curveMode": 4, - "curveTo": "{1, 0.7552587665785131}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{1, 0.45345861227894851}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.57117966666666675, 0.42196930230056767}", - "curveMode": 4, - "curveTo": "{0.57584633333333335, 0.41737835464371065}", - "hasCurveFrom": true, - "hasCurveTo": false, - "point": "{0.57584633333333335, 0.41737835464371065}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.5416293333333333, 0.44519392272210834}", - "curveMode": 4, - "curveTo": "{0.56651822222222215, 0.42573704931923878}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.56174044444444449, 0.42890698936802091}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.47911111111111115, 0.45345861227894851}", - "curveMode": 2, - "curveTo": "{0.52094444444444443, 0.45345861227894851}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0.45345861227894851}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.43364322222222224, 0.42573704931923878}", - "curveMode": 4, - "curveTo": "{0.45847655555555555, 0.44519392272210834}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.43847655555555559, 0.42890698936802091}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.42415366666666671, 0.41716487557766679}", - "curveMode": 4, - "curveTo": "{0.42887588888888889, 0.42186513151206773}", - "hasCurveFrom": false, - "hasCurveTo": true, - "point": "{0.42415366666666671, 0.41716487557766679}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 7.115451777777775, - "width": 14, - "x": 4.666666666666667, - "y": 10.77343711111111 - }, - "id": "AF491D30-B5FE-41DF-869C-AB5314DF7ABA", - "type": "shapePath", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B2C15FB3-E0D0-4505-AE27-341B3F7A64F2", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "vector" - } - ], - "pbdfType": "image" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/36EB4CE8-41DD-4EDE-A4BD-ED88D043D9F1.png" - }, - { - "pbdfType": "symbol_master", - "id": "bbd21e46-ad9d-4372-ae85-42558046da42", - "name": "Community Groups", - "convert": false, - "type": "artboard", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person/6", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "97736C0F-6E1F-4671-912F-003C97ACDE40", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [ - { - "overrideName": "F67563A5-78FC-433D-9E6C-8061F7E2F776_image", - "canOverride": true - } - ], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 1230, - "y": 0 - }, - "id": "53D04C05-9E5D-4F7A-8765-7DBEA892D0B5", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "5341CCB2-B409-4F09-A2E4-5202079F452D", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 11", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "constraints": { - "scaleFactor": 1, - "model_version": 0.1, - "aspectRatio": { - "multiplier": 41, - "enabled": 1, - "model_version": 0.1, - "modelID": "constraint_212aa1aa-8134-4254-9cf4-683c710bd4bb", - "model_class": "ADModelConstraint", - "constant": 41 - }, - "modelID": "viewConstraints_34fef27b-98f3-4757-bfb1-b162b31f962d", - "model_class": "ADModelViewConstraints", - "automatic": 1 - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "9B661BE6-C82B-46A3-B298-E355595772E2", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "323C5208-F3AB-4CE1-AD18-96FA196F6D2E", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Oval", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": true, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614237490000004, 1}", - "curveMode": 2, - "curveTo": "{0.22385762510000001, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385762510000001}", - "curveMode": 2, - "curveTo": "{1, 0.77614237490000004}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22385762510000001, 0}", - "curveMode": 2, - "curveTo": "{0.77614237490000004, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77614237490000004}", - "curveMode": 2, - "curveTo": "{0, 0.22385762510000001}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "F45DE24F-341B-4EBC-8CA9-434FE8C04FB8", - "type": "oval", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "8BE4D1EE-EEEA-418C-BA4F-F4F90AE4DF66", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 5.857142857142858, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 0.5857142857142857 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.0616508152173913, - "blue": 0, - "green": 0, - "red": 0 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "oval" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "MV5BMjAwMzc5OTEzOF5BMl5BanBnXkFtZTgwMDc5ODU3MTE@._V1_UX172_CR0,0,172,256_AL_", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "constraints": { - "scaleFactor": 1, - "model_version": 0.1, - "aspectRatio": { - "model_class": "ADModelConstraint", - "enabled": 1, - "multiplier": 41, - "constant": 61, - "model_version": 0.1, - "modelID": "constraint_ff6a7e0f-e880-4401-882c-d9b53d88e120" - }, - "modelID": "viewConstraints_8ca9ba1e-3c76-47de-80f2-3c91550c3575", - "model_class": "ADModelViewConstraints", - "automatic": 1 - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 0, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 61, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "F67563A5-78FC-433D-9E6C-8061F7E2F776", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/4be294aa4b0e0bdaf4069cdbab5dc3b764fc83c7.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "AE8A5B75-166C-40AA-B758-C932BE85F68A", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/BBD21E46-AD9D-4372-AE85-42558046DA42.png" - }, - { - "pbdfType": "symbol_master", - "id": "3a06138a-40e2-40d7-90cb-56bad609d9ce", - "name": "HomeScreenAlt", - "convert": false, - "type": "artboard", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person/8", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "477112E3-2915-42AA-96E2-BFD71521C33D", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [ - { - "overrideName": "B3428CE0-A493-4780-BF75-94D46A40EE17_image", - "canOverride": true - } - ], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 1230, - "y": 141 - }, - "id": "B8F978E3-16B6-4278-B836-B67E3F123C68", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "0A2BFDE7-7737-4220-8EF2-36CD1B43292E", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 9 Copy", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "3AA512BC-7AF9-4446-9015-3DCB996B0D56", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "ED53BDD5-289B-456C-A347-A72A4CBFEC55", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Oval", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": true, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614237490000004, 1}", - "curveMode": 2, - "curveTo": "{0.22385762510000001, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385762510000001}", - "curveMode": 2, - "curveTo": "{1, 0.77614237490000004}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22385762510000001, 0}", - "curveMode": 2, - "curveTo": "{0.77614237490000004, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77614237490000004}", - "curveMode": 2, - "curveTo": "{0, 0.22385762510000001}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "112378C3-B964-43C7-9CED-E348CBAC77D2", - "type": "oval", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "0C8AC1F3-21BF-41F3-A116-88544B2ABBCA", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 5.857142857142858, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 0.5857142857142857 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.0616508152173913, - "blue": 0, - "green": 0, - "red": 0 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "oval" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "download", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "constraints": { - "scaleFactor": 1, - "model_version": 0.1, - "aspectRatio": { - "model_class": "ADModelConstraint", - "enabled": 1, - "multiplier": 42, - "constant": 42, - "model_version": 0.1, - "modelID": "constraint_3ffbdf65-7ae0-4948-a2e4-14febc075d9b" - }, - "modelID": "viewConstraints_7c165554-f167-4856-bf00-daff5ec0c599", - "model_class": "ADModelViewConstraints", - "automatic": 1 - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 0, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 42, - "width": 42, - "x": -1, - "y": 0 - }, - "id": "B3428CE0-A493-4780-BF75-94D46A40EE17", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/4f1f017d838e74f4de4044aea323e97ae14f8f05.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "FBAD415A-6E7A-4457-8200-D4D906DB680B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/3A06138A-40E2-40D7-90CB-56BAD609D9CE.png" - }, - { - "pbdfType": "symbol_master", - "id": "c1aa2b99-e400-4e44-9000-e19a547ed3b9", - "name": "LearningOverviewAlt", - "convert": false, - "type": "artboard", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person/4", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "29155DF5-855F-4948-9C6C-935F9F9DD81E", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [ - { - "overrideName": "70B94A2C-C684-4AB5-AFE5-4CA194D59039_image", - "canOverride": true - } - ], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 1230, - "y": 282 - }, - "id": "24A06315-FBDB-489C-A4E5-5359CA2A4217", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "7624D8A0-B22B-478B-966A-71253E3532AA", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Group 7", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "708B0958-9512-42A8-A94D-C48381DE30FE", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "47DAA81A-D2B7-40A7-AC07-AEEA7F77140C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Oval", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": true, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614237490000004, 1}", - "curveMode": 2, - "curveTo": "{0.22385762510000001, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385762510000001}", - "curveMode": 2, - "curveTo": "{1, 0.77614237490000004}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22385762510000001, 0}", - "curveMode": 2, - "curveTo": "{0.77614237490000004, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77614237490000004}", - "curveMode": 2, - "curveTo": "{0, 0.22385762510000001}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "07415BF8-21D2-4417-8542-517B64BA3AB9", - "type": "oval", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "0A039717-5343-4BCC-A703-439E5041B1AB", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 5.857142857142858, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 0.5857142857142857 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.0616508152173913, - "blue": 0, - "green": 0, - "red": 0 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "oval" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "MV5BMTc0MzY2NjE0Nl5BMl5BanBnXkFtZTYwMDkxMDY0._V1_UY256_CR4,0,172,256_AL_", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 0, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 62, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "70B94A2C-C684-4AB5-AFE5-4CA194D59039", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/8c99aefa573b3ac7a325743d62ee07308c001cff.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "76450906-7605-4044-98C4-899A8702E351", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/C1AA2B99-E400-4E44-9000-E19A547ED3B9.png" - }, - { - "pbdfType": "symbol_master", - "id": "c756078b-9e00-45cf-8978-050e04f39e68", - "name": "person/frame", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person/frame", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 0.6509803922, - "green": 0.5764705882, - "red": 0.5333333333 - }, - "hasBackgroundColor": true, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": false, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 1230, - "y": 423 - }, - "id": "C756078B-9E00-45CF-8978-050E04F39E68", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E7CB6903-D45C-441E-9543-A5C17A761A67", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Oval", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": true, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "constraints": { - "scaleFactor": 1, - "model_version": 0.1, - "aspectRatio": { - "model_version": 0.1, - "enabled": 1, - "multiplier": 41, - "modelID": "constraint_64c14f23-c51a-4738-8138-7d8c1b67276e", - "model_class": "ADModelConstraint", - "constant": 41 - }, - "modelID": "viewConstraints_0101f9cb-7927-444d-9e59-4bd5d783a3f7", - "model_class": "ADModelViewConstraints", - "automatic": 1 - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614237490000004, 1}", - "curveMode": 2, - "curveTo": "{0.22385762510000001, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385762510000001}", - "curveMode": 2, - "curveTo": "{1, 0.77614237490000004}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22385762510000001, 0}", - "curveMode": 2, - "curveTo": "{0.77614237490000004, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77614237490000004}", - "curveMode": 2, - "curveTo": "{0, 0.22385762510000001}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "33D3EB50-74A6-45C9-99F5-77F7FBD13585", - "type": "oval", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "294B039E-96F7-4D90-97C1-97F074B5EB5B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 5.857142857142858, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 2, - "thickness": 2 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.0616508152173913, - "blue": 0, - "green": 0, - "red": 0 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "oval" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/C756078B-9E00-45CF-8978-050E04F39E68.png" - }, - { - "pbdfType": "symbol_master", - "id": "277a3d19-a01b-4e11-8f57-7c6d9b49749c", - "name": "person/1", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person/1", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "530E093C-4A76-41F1-9482-08004D962CD5", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [ - { - "overrideName": "B02B6AD6-5AD3-42B8-8234-715FC6EADCC6_image", - "canOverride": true - } - ], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 1230, - "y": 564 - }, - "id": "277A3D19-A01B-4E11-8F57-7C6D9B49749C", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "F2BD420D-6954-4B73-B256-04983CEC5DBE", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Group 4 Copy 3", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "399739F3-65D1-4732-BEAA-ECAC4C0D7FA1", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "7E50370E-1A23-400B-85BA-89B01F07E317", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Oval", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": true, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614237490000004, 1}", - "curveMode": 2, - "curveTo": "{0.22385762510000001, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385762510000001}", - "curveMode": 2, - "curveTo": "{1, 0.77614237490000004}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22385762510000001, 0}", - "curveMode": 2, - "curveTo": "{0.77614237490000004, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77614237490000004}", - "curveMode": 2, - "curveTo": "{0, 0.22385762510000001}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "75DA22C0-6FCC-4829-979A-08983DF78209", - "type": "oval", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "6D42CFB1-2DDA-4B3A-BCA6-5BEAC0EEF880", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 5.857142857142858, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 0.5857142857142857 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "oval" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "bearded-men-face-hipster-character-vector-14648253", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 0, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 43, - "width": 29, - "x": 6, - "y": 2 - }, - "id": "B02B6AD6-5AD3-42B8-8234-715FC6EADCC6", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/c74946529ab658fcc8913a8b157de9a55e262ce4.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "E02D5A6E-08BE-4541-A7FB-0F467F736480", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 0.3796296296296297, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0.2125211148648649, - "contrast": 2.480996621621621, - "hue": 1.159855311402397, - "saturation": 1.438978040540541 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/277A3D19-A01B-4E11-8F57-7C6D9B49749C.png" - }, - { - "pbdfType": "symbol_master", - "id": "ac76fba2-f9ca-4dee-94ed-03918f4ce652", - "name": "person/5", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person/5", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "00121EBB-86F2-4C74-8A1D-074B52B33010", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [ - { - "overrideName": "388230FE-E1E6-4477-BE2B-11FE9FF128F4_image", - "canOverride": true - } - ], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 1230, - "y": 705 - }, - "id": "AC76FBA2-F9CA-4DEE-94ED-03918F4CE652", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "3275527D-FC53-4D07-A11A-65177A1F519C", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "Group 8", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "B0A671DA-E5C3-4CA1-8129-DF398438902A", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "467F0FEA-A4AB-4BD4-814B-647B24C60DEF", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Oval", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": true, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614237490000004, 1}", - "curveMode": 2, - "curveTo": "{0.22385762510000001, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385762510000001}", - "curveMode": 2, - "curveTo": "{1, 0.77614237490000004}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22385762510000001, 0}", - "curveMode": 2, - "curveTo": "{0.77614237490000004, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77614237490000004}", - "curveMode": 2, - "curveTo": "{0, 0.22385762510000001}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "FF9FDA24-0C64-402A-B9C3-0B922A3B6A04", - "type": "oval", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "87AFDB99-5BDD-4DD3-9D46-187EB372CE68", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 5.857142857142858, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 0.5857142857142857 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.0616508152173913, - "blue": 0, - "green": 0, - "red": 0 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "oval" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "mens-slicked-back-grey-hair", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 0, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 47, - "width": 47, - "x": -3, - "y": 0 - }, - "id": "388230FE-E1E6-4477-BE2B-11FE9FF128F4", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/673b50671b86db7b6d722350ca4e47ec7c5e5f52.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "FFE7EF38-DBD5-46F2-86C0-265C6EAC4D90", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 4, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/AC76FBA2-F9CA-4DEE-94ED-03918F4CE652.png" - }, - { - "pbdfType": "symbol_master", - "id": "14464801-56ae-4b2e-888b-b7c56bb513dc", - "name": "person/12", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person/12", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "292AFD52-31A6-40B2-B087-3C35E9191616", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [ - { - "overrideName": "92EE7045-3A4C-4166-9326-40BE5FA11EF7_image", - "canOverride": true - } - ], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 1230, - "y": 846 - }, - "id": "14464801-56AE-4B2E-888B-B7C56BB513DC", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "CD7C7831-B5CB-42C8-8761-6F5F0D8C3C75", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Group 7", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": { - "constraints": { - "scaleFactor": 1, - "model_version": 0.1, - "aspectRatio": { - "model_class": "ADModelConstraint", - "enabled": 1, - "multiplier": 41, - "constant": 41, - "model_version": 0.1, - "modelID": "constraint_436decaf-18f5-4cd1-baa0-f343c56826c7" - }, - "modelID": "viewConstraints_b50092e9-7d9c-49c8-8fae-95464d18dd5c", - "model_class": "ADModelViewConstraints", - "automatic": 1 - } - } - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "9A8DF34F-5EEC-4FCA-9514-89713859A478", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "415CF93C-9E50-4E13-A3AB-9271B491FFDD", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "Oval", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": true, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.77614237490000004, 1}", - "curveMode": 2, - "curveTo": "{0.22385762510000001, 1}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0.22385762510000001}", - "curveMode": 2, - "curveTo": "{1, 0.77614237490000004}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{1, 0.5}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0.22385762510000001, 0}", - "curveMode": 2, - "curveTo": "{0.77614237490000004, 0}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0.5, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0.77614237490000004}", - "curveMode": 2, - "curveTo": "{0, 0.22385762510000001}", - "hasCurveFrom": true, - "hasCurveTo": true, - "point": "{0, 0.5}" - } - ], - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "8A87A39C-6EB4-4443-A3A3-405212186435", - "type": "oval", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B4C606FA-FEEB-46E6-A0DD-A56AFFA4D328", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 5.857142857142858, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": false, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 0, - "thickness": 0.5857142857142857 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 0.0616508152173913, - "blue": 0, - "green": 0, - "red": 0 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "oval" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "images (2)", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "fillReplacesImage": false, - "intendedDPI": 0, - "clippingMask": "{{0, 0}, {1, 1}}", - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": true, - "height": 42, - "width": 63, - "x": -18, - "y": 0 - }, - "id": "92EE7045-3A4C-4166-9326-40BE5FA11EF7", - "image": { - "_class": "MSJSONFileReference", - "_ref_class": "MSImageData", - "_ref": "images/9a74d63a137c7d69f65ba54a0e0e71f27b9a080f.png" - }, - "type": "bitmap", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "360D4F38-39DE-45AE-902D-C7E25E3EF2D9", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "image" - } - ], - "pbdfType": "group" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/14464801-56AE-4B2E-888B-B7C56BB513DC.png" - }, - { - "pbdfType": "symbol_master", - "id": "2c9ab975-28fc-40c1-ad16-a32bba023e53", - "name": "person/withframe", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "person/withframe", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "1E69FEC0-85F8-42BA-A987-F973EC2F19A8", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [ - { - "overrideName": "A268549D-9BCF-41CE-B386-6FFC1C85817B_symbolID", - "canOverride": true - }, - { - "overrideName": "772F0483-EB30-4642-AA0D-D56765C12CB4_symbolID", - "canOverride": true - } - ], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 1230, - "y": 987 - }, - "id": "2C9AB975-28FC-40C1-AD16-A32BBA023E53", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "B9785886-AE99-4DF6-B282-86FA0DC4AE05", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 1, - "name": "person/5", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "00121EBB-86F2-4C74-8A1D-074B52B33010", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "A268549D-9BCF-41CE-B386-6FFC1C85817B", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "16963334-55FD-44FA-9D5D-97FBEB09D968", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - }, - { - "booleanOperation": 0, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "person/frame", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": { - "com.animaapp.stc-sketch-plugin": { - "kModelPropertiesKey": {} - } - }, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "CLASS_NAME": null, - "overrideValues": [], - "scale": 1, - "symbolID": "A7CAA928-EC5F-4771-87DB-4CB45CB12DB6", - "verticalSpacing": 0, - "horizontalSpacing": 0, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 41, - "width": 41, - "x": 0, - "y": 0 - }, - "id": "772F0483-EB30-4642-AA0D-D56765C12CB4", - "type": "symbolInstance", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "04DB914B-AC53-4083-8348-9EDD919A45C8", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": true, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "parameters": null, - "pbdfType": "symbol_instance" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/2C9AB975-28FC-40C1-AD16-A32BBA023E53.png" - }, - { - "pbdfType": "symbol_master", - "id": "d377e55e-2dc6-446a-ac51-4c913a2b5692", - "name": "someElement/green", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "someElement/green", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "720A6B85-4F0B-45A3-96E0-3E9F50E46030", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 802, - "width": 979, - "x": 1371, - "y": 0 - }, - "id": "D377E55E-2DC6-446A-AC51-4C913A2B5692", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "20B93881-5A3E-4CEA-9DD1-7361412A3768", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "someElement/green", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 802, - "width": 979, - "x": 0, - "y": 0 - }, - "id": "CDE1848E-3FE3-4E75-A093-6510D452900F", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "1AE10229-B3F3-4F91-A6A0-BB0423999D44", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Rectangle", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 0, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 802, - "width": 979, - "x": 0, - "y": 0 - }, - "id": "6B7732F9-92DE-424D-AC15-A7C2305FC1B5", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "8AECAF89-8D3A-4D9A-8A77-FE15AD111F0B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 1, - "red": 0.2818509615384617 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - } - ], - "pbdfType": "group" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/D377E55E-2DC6-446A-AC51-4C913A2B5692.png" - }, - { - "pbdfType": "symbol_master", - "id": "d5f9ba19-3b15-490c-b31b-24aa26d8b77b", - "name": "someElement/default", - "convert": true, - "type": "symbolMaster", - "designNode": { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "someElement/default", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": true, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": true, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "backgroundColor": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - }, - "hasBackgroundColor": false, - "horizontalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInExport": true, - "includeInCloudUpload": true, - "isFlowHome": false, - "resizesContent": false, - "verticalRulerData": { - "_class": "rulerData", - "base": 0, - "guides": [] - }, - "includeBackgroundColorInInstance": false, - "symbolID": "3156C515-06F6-428E-8A5B-CB8B85B1F7F4", - "changeIdentifier": null, - "allowsOverrides": true, - "overrideProperties": [], - "presetDictionary": {}, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 802, - "width": 979, - "x": 1371, - "y": 902 - }, - "id": "D5F9BA19-3B15-490C-B31B-24AA26D8B77B", - "type": "symbolMaster", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "D471BC9E-BD31-484D-9CCA-D46CD7156BDD", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 2, - "name": "someElement/default", - "nameIsFixed": true, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "hasClickThrough": false, - "groupLayout": { - "_class": "MSImmutableFreeformGroupLayout" - }, - "CLASS_NAME": null, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 802, - "width": 979, - "x": 0, - "y": 0 - }, - "id": "F0D33876-5FA6-4524-A801-2F7F02351BB5", - "_ref": null, - "type": "group", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "FDB1A576-529D-4291-AAA3-1089F6E4AAB5", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "children": [ - { - "booleanOperation": -1, - "exportOptions": { - "_class": "exportOptions", - "includedLayerIds": [], - "layerOptions": 0, - "shouldTrim": false, - "exportFormats": [] - }, - "flow": null, - "isFixedToViewport": false, - "isFlippedHorizontal": false, - "isFlippedVertical": false, - "isLocked": false, - "layerListExpandedType": 0, - "name": "Rectangle", - "nameIsFixed": false, - "resizingConstraint": 63, - "resizingType": 0, - "rotation": 0, - "sharedStyleID": null, - "shouldBreakMaskChain": false, - "hasClippingMask": false, - "clippingMaskMode": 0, - "userInfo": null, - "maintainScrollPosition": null, - "prototypeNodeUUID": null, - "edited": false, - "isClosed": true, - "pointRadiusBehaviour": 1, - "points": [ - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 0}", - "curveMode": 1, - "curveTo": "{0, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 0}", - "curveMode": 1, - "curveTo": "{1, 0}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 0}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{1, 1}", - "curveMode": 1, - "curveTo": "{1, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{1, 1}" - }, - { - "_class": "curvePoint", - "cornerRadius": 0, - "curveFrom": "{0, 1}", - "curveMode": 1, - "curveTo": "{0, 1}", - "hasCurveFrom": false, - "hasCurveTo": false, - "point": "{0, 1}" - } - ], - "CLASS_NAME": null, - "fixedRadius": 0, - "hasConvertedToNewRoundCorners": true, - "needsConvertionToNewRoundCorners": false, - "absoluteBoundingBox": { - "_class": "rect", - "constrainProportions": false, - "height": 802, - "width": 979, - "x": 0, - "y": 0 - }, - "id": "2709F189-5E1B-478A-B3BC-D85FDE80B12F", - "type": "rectangle", - "visible": true, - "style": { - "_class": "style", - "do_objectID": "19705913-413B-4EF3-A749-6BE4FEC71E5B", - "endMarkerType": 0, - "miterLimit": 10, - "startMarkerType": 0, - "windingRule": 1, - "blur": { - "_class": "blur", - "isEnabled": false, - "center": "{0.5, 0.5}", - "motionAngle": 0, - "radius": 10, - "saturation": 1, - "type": 0 - }, - "borderOptions": { - "_class": "borderOptions", - "isEnabled": true, - "dashPattern": [], - "lineCapStyle": 0, - "lineJoinStyle": 0 - }, - "borders": [ - { - "_class": "border", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.592, - "green": 0.592, - "red": 0.592 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "position": 1, - "thickness": 1 - } - ], - "colorControls": { - "_class": "colorControls", - "isEnabled": false, - "brightness": 0, - "contrast": 1, - "hue": 0, - "saturation": 1 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "fills": [ - { - "_class": "fill", - "isEnabled": true, - "fillType": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0.847, - "green": 0.847, - "red": 0.847 - }, - "contextSettings": { - "_class": "graphicsContextSettings", - "blendMode": 0, - "opacity": 1 - }, - "gradient": { - "_class": "gradient", - "elipseLength": 0, - "from": "{0.5, 0}", - "gradientType": 0, - "to": "{0.5, 1}", - "stops": [ - { - "_class": "gradientStop", - "position": 0, - "color": { - "_class": "color", - "alpha": 1, - "blue": 1, - "green": 1, - "red": 1 - } - }, - { - "_class": "gradientStop", - "position": 1, - "color": { - "_class": "color", - "alpha": 1, - "blue": 0, - "green": 0, - "red": 0 - } - } - ] - }, - "noiseIndex": 0, - "noiseIntensity": 0, - "patternFillType": 1, - "patternTileScale": 1 - } - ], - "innerShadows": null, - "shadows": null, - "textStyle": null - }, - "pbdfType": "rectangle" - } - ], - "pbdfType": "group" - } - ], - "parameters": null, - "pbdfType": "symbol_master" - }, - "azure_blob_uri": "/D5F9BA19-3B15-490C-B31B-24AA26D8B77B.png" - } - ] - } - ], - "miscPages": [ - { - "pbdfType": "design_page", - "id": "C056F644-E132-461B-84D6-9B3ABCACFD0C", - "name": "third_party_widgets", - "convert": true, - "screens": [] - } - ], - "azure_container_uri": "" -} \ No newline at end of file diff --git a/TESTJSON/temp.json b/TESTJSON/temp.json deleted file mode 100644 index 98c6894c..00000000 --- a/TESTJSON/temp.json +++ /dev/null @@ -1 +0,0 @@ -{"projectName":"temp","pbdfType":"project","id":"5YVG9vFxbbmoFIhw2MxuIL","pages":[{"pbdfType":"design_page","id":"0:66","name":"Index Screens","convert":true,"screens":[{"pbdfType":"screen","id":"0:67","name":"Majors Overview","convert":true,"type":null,"designNode":{"id":"0:67","name":"Majors Overview","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":812.0,"width":375.0,"x":690.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:68","name":"header","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":690.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:69","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":690.0,"y":-295.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","visible":false,"type":"GRADIENT_LINEAR","gradientHandlePositions":[{"x":1.5,"y":0.5},{"x":0.5,"y":-0.5},{"x":2.0,"y":0.0}],"gradientStops":[{"color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0},"position":0.0},{"color":{"r":0.21176470816135406,"g":0.33725491166114807,"b":0.7647058963775635,"a":1.0},"position":1.0}]},{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:70","name":"userScore","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":70.0,"x":844.0,"y":-244.0},"transitionNodeID":null,"children":[{"id":"0:71","name":"285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":27.0,"width":38.0,"x":844.0,"y":-244.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:72","name":"starIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":22.0,"x":892.0,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"561adcc26e02e562330294d1ef7cb73d7d78b1b5","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:73","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":30.0,"width":25.161291122436523,"x":707.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fc4b89babe0fe59e003d8203615ac3d519f96daa","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:74","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":34.0,"width":34.0,"x":1016.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:75","name":"Recommended Majors","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":179.0,"x":707.0,"y":-6.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Recommended Majors","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:76","name":"Favorites","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":74.0,"x":707.0,"y":-129.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Favorites","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:77","name":"SmallMajorCard","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":-96.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:77;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":-96.0},"transitionNodeID":null,"children":[{"id":"I0:77;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":-96.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:77;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":719.0,"y":-83.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:77;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":-88.0},"transitionNodeID":null,"children":[{"id":"I0:77;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":-88.0},"transitionNodeID":null,"children":[{"id":"I0:77;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":-88.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:77;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":839.0,"y":-82.0},"transitionNodeID":null,"children":[{"id":"I0:77;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":840.6666870117188,"y":-79.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:78","name":"SmallMajorCard Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":-96.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:78;0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":-96.0},"transitionNodeID":null,"children":[{"id":"I0:78;0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":-96.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:78;0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":897.0,"y":-83.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:78;41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":-88.0},"transitionNodeID":null,"children":[{"id":"I0:78;41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":-88.0},"transitionNodeID":null,"children":[{"id":"I0:78;41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":-88.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:78;41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1017.0,"y":-82.0},"transitionNodeID":null,"children":[{"id":"I0:78;41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1018.6666870117188,"y":-79.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:56","pbdfType":null},{"id":"0:79","name":"1. Bars / 2. Top Bar / 2. Large / Heading + Search","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":113.0,"x":705.0,"y":-182.0},"transitionNodeID":null,"children":[{"id":"0:80","name":"🅰️ Heading","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":104.0,"x":705.0,"y":-182.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.014475814066827297,"g":0.1713331937789917,"b":0.36188071966171265,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Majors","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:81","name":"SmallMajorCard","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":31.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:81;0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":31.0},"transitionNodeID":null,"children":[{"id":"I0:81;0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":31.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:81;0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":718.0,"y":44.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:81;41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":39.0},"transitionNodeID":null,"children":[{"id":"I0:81;41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":39.0},"transitionNodeID":null,"children":[{"id":"I0:81;41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":39.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:81;41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":838.0,"y":45.0},"transitionNodeID":null,"children":[{"id":"I0:81;41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":839.6666870117188,"y":47.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:56","pbdfType":null},{"id":"0:82","name":"SmallMajorCard Copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":124.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:82;0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"I0:82;0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":124.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:82;0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":718.0,"y":137.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:82;41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":132.0},"transitionNodeID":null,"children":[{"id":"I0:82;41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":132.0},"transitionNodeID":null,"children":[{"id":"I0:82;41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":132.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:82;41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":838.0,"y":138.0},"transitionNodeID":null,"children":[{"id":"I0:82;41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":839.6666870117188,"y":140.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:56","pbdfType":null},{"id":"0:83","name":"SmallMajorCard Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":124.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:83;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"I0:83;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":124.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:83;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":896.0,"y":137.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:83;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":132.0},"transitionNodeID":null,"children":[{"id":"I0:83;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":132.0},"transitionNodeID":null,"children":[{"id":"I0:83;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":132.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:83;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1016.0,"y":138.0},"transitionNodeID":null,"children":[{"id":"I0:83;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1017.6666870117188,"y":140.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:84","name":"SmallMajorCard Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":31.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:84;0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":31.0},"transitionNodeID":null,"children":[{"id":"I0:84;0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":31.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:84;0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":896.0,"y":44.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:84;41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":39.0},"transitionNodeID":null,"children":[{"id":"I0:84;41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":39.0},"transitionNodeID":null,"children":[{"id":"I0:84;41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":39.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:84;41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1016.0,"y":45.0},"transitionNodeID":null,"children":[{"id":"I0:84;41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1017.6666870117188,"y":47.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:56","pbdfType":null},{"id":"0:85","name":"Most Popular Majors","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":167.0,"x":707.0,"y":221.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Most Popular Majors","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:86","name":"SmallMajorCard","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":254.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:86;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":254.0},"transitionNodeID":null,"children":[{"id":"I0:86;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":706.0,"y":254.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:86;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":718.0,"y":267.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:86;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":262.0},"transitionNodeID":null,"children":[{"id":"I0:86;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":262.0},"transitionNodeID":null,"children":[{"id":"I0:86;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":832.0,"y":262.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:86;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":838.0,"y":268.0},"transitionNodeID":null,"children":[{"id":"I0:86;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":839.6666870117188,"y":270.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:87","name":"SmallMajorCard Copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":347.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:87;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":347.0},"transitionNodeID":null,"children":[{"id":"I0:87;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":707.0,"y":347.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:87;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":719.0,"y":360.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:87;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":355.0},"transitionNodeID":null,"children":[{"id":"I0:87;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":355.0},"transitionNodeID":null,"children":[{"id":"I0:87;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":833.0,"y":355.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:87;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":839.0,"y":361.0},"transitionNodeID":null,"children":[{"id":"I0:87;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":840.6666870117188,"y":363.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:88","name":"SmallMajorCard Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":347.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:88;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":347.0},"transitionNodeID":null,"children":[{"id":"I0:88;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":885.0,"y":347.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:88;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":897.0,"y":360.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:88;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":355.0},"transitionNodeID":null,"children":[{"id":"I0:88;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":355.0},"transitionNodeID":null,"children":[{"id":"I0:88;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1011.0,"y":355.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:88;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1017.0,"y":361.0},"transitionNodeID":null,"children":[{"id":"I0:88;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1018.6666870117188,"y":363.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:89","name":"SmallMajorCard Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":254.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:89;0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":254.0},"transitionNodeID":null,"children":[{"id":"I0:89;0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":884.0,"y":254.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"I0:89;0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":896.0,"y":267.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"I0:89;41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":262.0},"transitionNodeID":null,"children":[{"id":"I0:89;41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":262.0},"transitionNodeID":null,"children":[{"id":"I0:89;41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1010.0,"y":262.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:89;41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1016.0,"y":268.0},"transitionNodeID":null,"children":[{"id":"I0:89;41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1017.6666870117188,"y":270.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"componentId":"0:61","pbdfType":null},{"id":"0:90","name":"Advanced Search","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.0,"width":119.0,"x":931.0,"y":-168.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.5568627715110779,"b":0.9490196108818054,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Advanced Search","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9490196108818054,"g":0.5568627715110779,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.9490196108818054,"g":0.5568627715110779,"r":0.21176470816135406},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:91","name":"normal","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":56.0,"width":302.0,"x":730.0,"y":439.0},"transitionNodeID":null,"children":[{"id":"0:95","name":"2homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":26.0,"x":730.0,"y":455.86328125},"transitionNodeID":"0:172","children":[{"id":"0:92","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":26.0,"x":730.0,"y":455.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:93","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":26.0,"x":730.0,"y":455.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:94","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.729411780834198,"g":0.6235294342041016,"r":0.5843137502670288},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":26.0,"x":730.0,"y":455.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5843137502670288,"g":0.6235294342041016,"b":0.729411780834198,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:96","name":"stats","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:119","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":938.0,"y":458.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"726d1978755b145b9ac3fd39d36552d1cec12b72","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:97","name":"plus-icon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":56.0,"width":50.90909194946289,"x":852.0,"y":439.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"05cf0e11c179692ec2fcb5eff64e817a9596d400","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:98","name":"not published","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":23.33333396911621,"width":23.33333396911621,"x":799.0,"y":457.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1bee5266944df41f0f6cd87832566d650163ddfe","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:99","name":"learn","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:214","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":21.0,"width":24.0,"x":1008.0,"y":462.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"b12d692ccfdf45980c55fc36de927c9ac37f466b","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:67.png"},{"pbdfType":"screen","id":"0:100","name":"Landing Page","convert":true,"type":null,"designNode":{"id":"0:100","name":"Landing Page","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":812.0,"width":375.0,"x":2154.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:101","name":"iPhone X Blue@3x","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":413.0,"width":221.0,"x":2232.0,"y":-189.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"acb2bef09f1e01f874c772febcb4ececdc2ab52d","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:102","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":271.0,"width":375.0,"x":2154.0,"y":246.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:103","name":"A new way to learn a","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":292.0,"x":2195.0,"y":268.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.014475814066827297,"g":0.1713331937789917,"b":0.36188071966171265,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"A new way to learn about careers","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:104","name":"Inspyred provides re","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":235.0,"x":2224.0,"y":297.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.46666666865348816,"g":0.5254902243614197,"b":0.6196078658103943,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Inspyred provides resources to help you make the best decisions.","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.6196078658103943,"g":0.5254902243614197,"r":0.46666666865348816},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.6196078658103943,"g":0.5254902243614197,"r":0.46666666865348816},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:105","name":"Main-button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2198.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:106","name":"Create Account","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2198.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:107","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2198.0,"y":369.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":100.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:108","name":"Sign Up","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":66.0,"x":2309.0,"y":381.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Sign Up","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:109","name":"Create Account","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2195.0,"y":430.0},"transitionNodeID":"0:172","children":[{"id":"0:110","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":1.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":288.0,"x":2195.0,"y":430.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":100.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:111","name":"Log in","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":55.0,"x":2311.5,"y":442.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.4921875,"g":0.4921875,"b":0.4921875,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Log in","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.4921875,"g":0.4921875,"r":0.4921875},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.4921875,"g":0.4921875,"r":0.4921875},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:112","name":"header","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":2154.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:113","name":"background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":2154.0,"y":-295.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","visible":false,"type":"GRADIENT_LINEAR","gradientHandlePositions":[{"x":1.5,"y":0.5},{"x":0.5,"y":-0.5},{"x":2.0,"y":0.0}],"gradientStops":[{"color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0},"position":0.0},{"color":{"r":0.21176470816135406,"g":0.33725491166114807,"b":0.7647058963775635,"a":1.0},"position":1.0}]},{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:114","name":"userScore","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":70.0,"x":2307.0,"y":-244.0},"transitionNodeID":null,"children":[{"id":"0:115","name":"285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":27.0,"width":40.0,"x":2307.0,"y":-244.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:116","name":"starIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":22.0,"x":2355.0,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"561adcc26e02e562330294d1ef7cb73d7d78b1b5","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:117","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":30.0,"width":25.0,"x":2171.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fc4b89babe0fe59e003d8203615ac3d519f96daa","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:118","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":34.0,"width":34.0,"x":2480.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:100.png"},{"pbdfType":"screen","id":"0:119","name":"Community Groups","convert":true,"type":null,"designNode":{"id":"0:119","name":"Community Groups","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":812.0,"width":375.0,"x":1679.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:120","name":"header","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":1679.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:121","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":375.0,"x":1679.0,"y":-295.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:122","name":"userScore","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":70.0,"x":1832.0,"y":-244.0},"transitionNodeID":null,"children":[{"id":"0:123","name":"285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":27.0,"width":38.0,"x":1832.0,"y":-244.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:124","name":"starIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":22.0,"x":1880.0,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"561adcc26e02e562330294d1ef7cb73d7d78b1b5","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:125","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":29.225807189941406,"width":25.161291122436523,"x":1696.0,"y":-246.22579956054688},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"70d7696e0256bf5b87fe826a9142b64539ece51a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:126","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":34.0,"width":34.0,"x":2005.0,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:127","name":"Your Groups","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":101.0,"x":1696.0,"y":-184.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Your Groups","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:128","name":"More Groups","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":105.0,"x":1696.0,"y":4.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"More Groups","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:129","name":"Cell1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":124.0,"width":245.0,"x":1696.0,"y":-147.0},"transitionNodeID":null,"children":[{"id":"0:130","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":1.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":124.0,"width":245.0,"x":1696.0,"y":-147.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"INSIDE","styles":null,"fills":[],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:131","name":"High School Group","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":155.0,"x":1710.0,"y":-134.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"High School Group","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:132","name":"People Group 1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":89.0,"x":1710.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:18","name":"person 9","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1710.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:19","name":"Group 8","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1710.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:20","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1710.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"29:21","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1710.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"29:22","name":"mens-slicked-back-grey-hair","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":47.0,"width":47.0,"x":1707.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"466b9d7e969ee5eae4fa60480890a3c382b99131","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"29:9","name":"person 9","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:10","name":"person/1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I29:10;0:29","name":"Group 4 Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I29:10;0:30","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I29:10;0:32","name":"bearded-men-face-hipster-character-vector-14648253","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":43.0,"width":29.0,"x":1740.0,"y":-77.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fa88d58c5f0e4e19ea1f1da0bc095f753c04260c","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:28","pbdfType":null},{"id":"79:111","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:112","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:113","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1734.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"29:0","name":"person 9 copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"29:1","name":"person/12","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I29:1;0:39","name":"Group 7","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I29:1;0:40","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I29:1;0:42","name":"images (2)","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":63.0,"x":1740.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"762e6bf5275df04d86809d5558393e736b689df2","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:38","pbdfType":null},{"id":"79:108","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:109","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:110","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1758.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:136","name":"Cell2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":124.0,"width":245.0,"x":1953.0,"y":-147.0},"transitionNodeID":null,"children":[{"id":"0:137","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":1.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":124.0,"width":245.0,"x":1953.0,"y":-147.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"INSIDE","styles":null,"fills":[],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:138","name":"Programming","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":112.0,"x":1979.0,"y":-134.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Programming","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:139","name":"People Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":89.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"0:140","name":"person 9 copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"0:141","name":"person/5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:141;0:21","name":"Group 7","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I0:141;0:22","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:141;0:24","name":"MV5BMTc0MzY2NjE0Nl5BMl5BanBnXkFtZTYwMDkxMDY0._V1_UY256_CR4,0,172,256_AL_","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":62.0,"width":41.0,"x":1979.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"da827996130fb49beae52d638023a3c521add634","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:20","pbdfType":null},{"id":"79:120","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:121","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:122","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1979.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:143","name":"person 9 copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"0:144","name":"person/5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:144;0:11","name":"Group 11","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I0:144;0:12","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:144;0:14","name":"MV5BMjAwMzc5OTEzOF5BMl5BanBnXkFtZTgwMDc5ODU3MTE@._V1_UX172_CR0,0,172,256_AL_","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":41.0,"x":2003.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"d3bd9ca71b3fe97e05ddf694a700390c236d4c38","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:10","pbdfType":null},{"id":"79:117","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:118","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:119","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2003.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:146","name":"person 9 copy 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"0:147","name":"person/5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:147;0:16","name":"Group 9 Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"I0:147;0:17","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"I0:147;0:19","name":"download","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":42.0,"x":2026.0,"y":-79.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"0ee38c205bd2ebee137b0ff0ba528cf791c37df6","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"componentId":"0:15","pbdfType":null},{"id":"79:114","name":"person/frame","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"transitionNodeID":null,"children":[{"id":"79:115","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"79:116","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":2027.0,"y":-79.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"strokeWeight":2.0,"strokeAlign":"OUTSIDE","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:149","name":"groups","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":344.0,"width":358.0,"x":1696.0,"y":77.0},"transitionNodeID":null,"children":[{"id":"0:150","name":"Algorithms","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":92.0,"x":1696.0,"y":77.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Algorithms","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:151","name":"Nursing","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":65.0,"x":1696.0,"y":142.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Nursing","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:152","name":"Dog Photos","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":94.0,"x":1696.0,"y":207.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Dog Photos","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:153","name":"Sports","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":54.0,"x":1696.0,"y":272.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Sports","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:154","name":"Band","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":42.0,"x":1696.0,"y":336.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Band","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:155","name":"Party time","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":86.0,"x":1696.0,"y":401.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Party time","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:156","name":"Line Copy","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":117.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:157","name":"Line Copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":182.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:158","name":"Line Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":247.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:159","name":"Line Copy 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":312.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:160","name":"Line Copy 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":2.0,"width":354.0,"x":1700.0,"y":376.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.7372549176216125,"g":0.7568627595901489,"b":0.7843137383460999,"a":1.0}}],"strokeWeight":1.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:161","name":"Line","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":1.0,"width":187.5,"x":1679.0,"y":42.0},"size":null,"strokes":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.5176470875740051,"b":1.0,"a":1.0}}],"strokeWeight":3.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:162","name":"normal","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":56.0,"width":302.0,"x":1719.0,"y":434.0},"transitionNodeID":null,"children":[{"id":"0:166","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":25.739999771118164,"x":1719.0,"y":450.86328125},"transitionNodeID":"0:172","children":[{"id":"0:163","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":25.739999771118164,"x":1719.0,"y":450.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:164","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":25.739999771118164,"x":1719.0,"y":450.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:165","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.729411780834198,"g":0.6235294342041016,"r":0.5843137502670288},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.2734375,"width":25.739999771118164,"x":1719.0,"y":450.86328125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5843137502670288,"g":0.6235294342041016,"b":0.729411780834198,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:167","name":"stats","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1927.0,"y":453.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"726d1978755b145b9ac3fd39d36552d1cec12b72","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:168","name":"plus-icon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":56.0,"width":50.90909194946289,"x":1841.0,"y":434.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"05cf0e11c179692ec2fcb5eff64e817a9596d400","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:169","name":"not published","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:67","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":23.33333396911621,"width":23.33333396911621,"x":1788.0,"y":452.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1bee5266944df41f0f6cd87832566d650163ddfe","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:170","name":"learn","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:214","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":21.0,"width":24.0,"x":1997.0,"y":457.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"b12d692ccfdf45980c55fc36de927c9ac37f466b","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:171","name":"Create New","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.0,"width":76.0,"x":1946.0,"y":-181.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.48235294222831726,"b":0.886274516582489,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Create New","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.886274516582489,"g":0.48235294222831726,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.886274516582489,"g":0.48235294222831726,"r":0.2078431397676468},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:119.png"},{"pbdfType":"screen","id":"0:172","name":"HomeScreenAlt","convert":true,"type":null,"designNode":{"id":"0:172","name":"HomeScreenAlt","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":896.0,"width":414.0,"x":1165.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:173","name":"Top Stack Section","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":610.0,"width":414.0,"x":1165.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:174","name":"backgroundImage","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":529.0,"width":414.0,"x":1165.0,"y":-295.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"65337f67361e93ec60270000b045aa826d92a5d8","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:175","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":258.0,"x":1244.0,"y":-164.0},"transitionNodeID":null,"children":[{"id":"0:176","name":"Noam Levine","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":115.76923370361328,"x":1314.5640869140625,"y":-163.5238037109375},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Noam Levine","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:177","name":"Student at Hanks Hig","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":256.8974304199219,"x":1244.55126953125,"y":-140.4761962890625},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Student at Hanks High School","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:178","name":"Completion Graph","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":88.0,"width":131.0,"x":1307.0,"y":-10.0},"transitionNodeID":null,"children":[{"id":"2:135","name":"Component 1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":87.32353210449219,"width":131.0,"x":1307.0,"y":-9.882352828979492},"transitionNodeID":null,"children":[{"id":"0:179","name":"72%","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":77.0,"width":131.0,"x":1307.0,"y":-9.882352828979492},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"72%","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:180","name":"Completed","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":91.3697509765625,"x":1326.815185546875,"y":58.44117736816406},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.800000011920929,"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Completed","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:181","name":"ScoreCard","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":128.0,"width":414.0,"x":1165.0,"y":187.0},"transitionNodeID":null,"children":[{"id":"0:182","name":"Score Bar@3x","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":128.0,"width":414.0,"x":1165.0,"y":187.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"ea2cf7390a161fe48fcd63570a39acf952b1eb54","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:183","name":"Score: 285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":28.0,"width":125.85600280761719,"x":1309.072021484375,"y":227.95040893554688},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21548150479793549,"g":0.19963327050209045,"b":0.19963327050209045,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Score: 285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.19963327050209045,"g":0.19963327050209045,"r":0.21548150479793549},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.19963327050209045,"g":0.19963327050209045,"r":0.21548150479793549},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[4.0,4.0,4.0,4.0,4.0,4.0,4.0,3.0,3.0,3.0],"styleOverrideTable":{"4":{"fontFamily":"Sanchez","fontPostScriptName":"Sanchez-Regular","fontWeight":400},"3":{"fontFamily":"Sanchez","fontPostScriptName":"Sanchez-Regular","fontWeight":400,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5372549295425415,"b":0.9333333373069763,"a":1.0}}]}},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:184","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":36.0,"width":38.0,"x":1522.0,"y":-245.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:185","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":30.0,"width":28.0,"x":1184.0,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"70d7696e0256bf5b87fe826a9142b64539ece51a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:186","name":"Connect Facebook Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":315.0},"transitionNodeID":null,"children":[{"id":"0:187","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":315.0},"transitionNodeID":null,"children":[{"id":"0:189","name":"Rectangle 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":315.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}},{"opacity":0.5,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.25882354378700256,"g":0.40392157435417175,"b":0.6980392336845398,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":30.5,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:188","name":"Rectangle 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":315.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}},{"opacity":0.5,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.25882354378700256,"g":0.40392157435417175,"b":0.6980392336845398,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":30.5,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:190","name":"Continue","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":190.0,"x":1289.0,"y":336.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Connect facebook","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:191","name":"Page 1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":61.0,"x":1201.0,"y":315.0},"transitionNodeID":null,"children":[{"id":"0:192","name":"Oval 5","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":61.0,"x":1201.0,"y":315.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.25882354378700256,"g":0.40392157435417175,"b":0.6980392336845398,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:193","name":"Fill 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":47.0,"width":25.0,"x":1225.0,"y":329.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:194","name":"Invite Friends Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":404.0},"transitionNodeID":null,"children":[{"id":"0:195","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":404.0},"transitionNodeID":null,"children":[{"id":"0:197","name":"Rectangle 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":404.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}},{"opacity":0.44999998807907104,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0941176488995552,"g":0.7882353067398071,"b":0.8901960849761963,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":30.5,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:196","name":"Rectangle 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":342.0,"x":1201.0,"y":404.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}},{"opacity":0.44999998807907104,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0941176488995552,"g":0.7882353067398071,"b":0.8901960849761963,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":30.5,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:198","name":"Invite Friends","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":146.0,"x":1289.0,"y":425.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Invite Friends","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:199","name":"Spotify Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":61.0,"x":1201.0,"y":404.0},"transitionNodeID":null,"children":[{"id":"0:200","name":"Spotify","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":61.0,"x":1201.0,"y":404.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0941176488995552,"g":0.7882353067398071,"b":0.8901960849761963,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:201","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":29.0,"width":44.0,"x":1210.0,"y":421.0},"transitionNodeID":null,"children":[{"id":"0:202","name":"Fill 4","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.0,"width":44.0,"x":1210.0,"y":421.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null},{"id":"0:203","name":"Fill 6","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":14.0,"width":26.0,"x":1219.0,"y":436.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:204","name":"person","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":82.0,"width":85.0,"x":1331.0,"y":-251.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"62b79ea6babc1f4ab6b7b3ffde1833016d810a9d","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:205","name":"normal","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":322.0,"x":1211.0,"y":521.0},"transitionNodeID":null,"children":[{"id":"0:209","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":27.719999313354492,"x":1211.0,"y":540.0},"transitionNodeID":null,"children":[{"id":"0:206","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":27.719999313354492,"x":1211.0,"y":540.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:207","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":27.719999313354492,"x":1211.0,"y":540.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:208","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.729411780834198,"g":0.6235294342041016,"r":0.5843137502670288},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":27.719999313354492,"x":1211.0,"y":540.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5843137502670288,"g":0.6235294342041016,"b":0.729411780834198,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:210","name":"stats","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:119","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":26.0,"x":1433.0,"y":542.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"726d1978755b145b9ac3fd39d36552d1cec12b72","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:211","name":"plus-icon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":54.0,"x":1341.0,"y":521.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"05cf0e11c179692ec2fcb5eff64e817a9596d400","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:212","name":"not published","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:67","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":25.0,"x":1285.0,"y":541.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1bee5266944df41f0f6cd87832566d650163ddfe","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:213","name":"learn","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:214","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":23.0,"width":26.0,"x":1507.0,"y":546.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"b12d692ccfdf45980c55fc36de927c9ac37f466b","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:172.png"},{"pbdfType":"screen","id":"0:214","name":"LearningOverviewAlt","convert":true,"type":null,"designNode":{"id":"0:214","name":"LearningOverviewAlt","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":896.0,"width":414.0,"x":176.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:215","name":"header","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":414.0,"x":176.0,"y":-295.0},"transitionNodeID":null,"children":[{"id":"0:216","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":95.0,"width":414.0,"x":176.0,"y":-295.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:217","name":"userScore","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":78.0,"x":344.9119873046875,"y":-244.0},"transitionNodeID":null,"children":[{"id":"0:218","name":"285","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":27.0,"width":38.0,"x":344.9119873046875,"y":-244.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"285","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:219","name":"starIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":24.288000106811523,"x":397.90399169921875,"y":-242.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"561adcc26e02e562330294d1ef7cb73d7d78b1b5","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:220","name":"bellIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":29.225807189941406,"width":27.778064727783203,"x":194.76800537109375,"y":-246.22579956054688},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"70d7696e0256bf5b87fe826a9142b64539ece51a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:221","name":"profileIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":34.0,"width":37.5359992980957,"x":535.9039916992188,"y":-247.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1970b23eb7b96f9c734db0864f2478d4c11d5893","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:222","name":"Categories","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":87.0,"x":199.0,"y":-135.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Categories","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:223","name":"1. Bars / 2. Top Bar / 2. Large / Heading + Search","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":126.0,"x":198.0,"y":-182.0},"transitionNodeID":null,"children":[{"id":"0:224","name":"🅰️ Heading","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":40.0,"width":120.0,"x":198.0,"y":-182.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.014475814066827297,"g":0.1713331937789917,"b":0.36188071966171265,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Explore","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.36188071966171265,"g":0.1713331937789917,"r":0.014475814066827297},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"0:225","name":"Group 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":198.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:226","name":"Group","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":198.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:227","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":198.0,"y":-97.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:228","name":"Careers","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":63.0,"x":220.0,"y":32.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Careers","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:229","name":"simplePaperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":74.0,"width":73.0,"x":214.0,"y":-69.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"2ce8b7c0c797b888993f960fa5e1accfb130705a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:230","name":"Group 2 Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":331.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:231","name":"Group","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":331.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:232","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":331.0,"y":-97.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:233","name":"Majors","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":54.0,"x":357.0,"y":32.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Majors","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:234","name":"simplePaperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":74.0,"width":73.0,"x":347.0,"y":-69.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"2ce8b7c0c797b888993f960fa5e1accfb130705a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:235","name":"Group 2 Copy 2","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":464.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:236","name":"Group","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":464.0,"y":-97.0},"transitionNodeID":null,"children":[{"id":"0:237","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9843137264251709,"g":0.5960784554481506,"r":0.2078431397676468},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":155.0,"width":105.0,"x":464.0,"y":-97.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.2078431397676468,"g":0.5960784554481506,"b":0.9843137264251709,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:238","name":"Colleges","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":69.0,"x":482.0,"y":32.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Colleges","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:239","name":"simplePaperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":74.0,"width":73.0,"x":480.0,"y":-69.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"2ce8b7c0c797b888993f960fa5e1accfb130705a","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:240","name":"Continue Learning","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":152.0,"x":199.0,"y":76.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Continue Learning","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:241","name":"View All","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.0,"width":58.0,"x":516.0,"y":80.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.5568627715110779,"b":0.9490196108818054,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"View All","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.9490196108818054,"g":0.5568627715110779,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.9490196108818054,"g":0.5568627715110779,"r":0.21176470816135406},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:242","name":"Lesson Big Card","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:243","name":"Group 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:244","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.772549033164978,"g":0.21176470816135406,"r":0.49803921580314636},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":124.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.49803921580314636,"g":0.21176470816135406,"b":0.772549033164978,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:245","name":"Fundamentals of Algo","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":115.0,"x":232.5,"y":138.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Fundamentals\nof Algorithms","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:246","name":"paperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":97.0,"width":97.0,"x":241.0,"y":198.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fc1e80e0188ea1eef90949eba199e5d82cc36845","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:247","name":"Group 5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:248","name":"Lesson Big Card Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:249","name":"Group 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:250","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.0,"g":0.0,"r":0.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":124.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.8500000238418579,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:251","name":"Finance","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":65.0,"x":444.0,"y":138.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Finance","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:252","name":"cashIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":93.0,"width":132.0,"x":410.0,"y":198.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"5afc3234c772299d4b12566e8f0b8229ec78c5d8","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:253","name":"Lessons","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":66.0,"x":212.0,"y":331.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.044722575694322586,"g":0.044722575694322586,"b":0.044722575694322586,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Lessons","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":0.044722575694322586,"g":0.044722575694322586,"r":0.044722575694322586},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:254","name":"Lesson Big Card","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:255","name":"Group 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:256","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.772549033164978,"g":0.21176470816135406,"r":0.49803921580314636},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":207.0,"y":369.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.49803921580314636,"g":0.21176470816135406,"b":0.772549033164978,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:257","name":"Fundamentals of Algo","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":115.0,"x":232.5,"y":383.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Fundamentals\nof Algorithms","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:258","name":"paperIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":97.0,"width":97.0,"x":241.0,"y":443.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fc1e80e0188ea1eef90949eba199e5d82cc36845","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:259","name":"Group 5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:260","name":"Lesson Big Card Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:261","name":"Group 4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":369.0},"transitionNodeID":null,"children":[{"id":"0:262","name":"Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.0,"g":0.0,"r":0.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":200.0,"width":165.0,"x":394.0,"y":369.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.8500000238418579,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":8.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:263","name":"Finance","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":22.0,"width":65.0,"x":444.0,"y":383.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Finance","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null},{"id":"0:264","name":"cashIcon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":93.0,"width":132.0,"x":410.0,"y":443.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"5afc3234c772299d4b12566e8f0b8229ec78c5d8","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:265","name":"normal","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":59.890907287597656,"width":322.0,"x":223.0,"y":523.7393798828125},"transitionNodeID":null,"children":[{"id":"0:269","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":28.0,"x":223.0,"y":542.0},"transitionNodeID":"0:172","children":[{"id":"0:266","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":28.0,"x":223.0,"y":542.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:267","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":28.0,"x":223.0,"y":542.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"21d91c427ebfba99ab3909151fb10464dae795de","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:268","name":"homeicon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.729411780834198,"g":0.6235294342041016,"r":0.5843137502670288},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":28.0,"x":223.0,"y":542.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5843137502670288,"g":0.6235294342041016,"b":0.729411780834198,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null},{"id":"0:270","name":"stats","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:119","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":26.0,"width":26.0,"x":445.0,"y":544.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"726d1978755b145b9ac3fd39d36552d1cec12b72","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:271","name":"plus-icon","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":59.890907287597656,"width":52.560001373291016,"x":353.7200012207031,"y":523.7393798828125},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"2820aa24bc5fef31f345f96b4c97f6337cef54c3","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:272","name":"not published","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":"0:67","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":25.0,"width":25.0,"x":297.0,"y":545.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"1bee5266944df41f0f6cd87832566d650163ddfe","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:273","name":"learn","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":23.0,"width":26.0,"x":519.0,"y":548.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"b12d692ccfdf45980c55fc36de927c9ac37f466b","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:214.png"}]},{"pbdfType":"design_page","id":"0:1","name":"Symbols","convert":true,"screens":[{"pbdfType":"screen","id":"0:61","name":"SmallMajorCard/loved","convert":true,"type":null,"designNode":{"id":"0:61","name":"SmallMajorCard/loved","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":148.0},"transitionNodeID":null,"children":[{"id":"0:62","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":148.0},"transitionNodeID":null,"children":[{"id":"0:63","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":148.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:64","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":1383.0,"y":161.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"41:172","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":156.0},"transitionNodeID":null,"children":[{"id":"41:173","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":156.0},"transitionNodeID":null,"children":[{"id":"41:174","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":156.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"41:225","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1503.0,"y":162.0},"transitionNodeID":null,"children":[{"id":"41:226","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1504.6666259765625,"y":164.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"type":"FRAME","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:61.png"},{"pbdfType":"screen","id":"0:56","name":"SmallMajorCard/default","convert":true,"type":null,"designNode":{"id":"0:56","name":"SmallMajorCard/default","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":-28.0},"transitionNodeID":null,"children":[{"id":"0:57","name":"Group Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":-28.0},"transitionNodeID":null,"children":[{"id":"0:58","name":"","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.7686274647712708,"g":0.34117648005485535,"r":0.21176470816135406},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":80.0,"width":165.0,"x":1371.0,"y":-28.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.21176470816135406,"g":0.34117648005485535,"b":0.7686274647712708,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":10.0,"rectangleCornerRadii":null,"pbdfType":null},{"id":"0:59","name":"Information Systems","pluginData":null,"sharedPluginData":null,"visible":true,"layoutAlign":null,"constraints":{"vertical":"CENTER","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":44.0,"width":117.0,"x":1383.0,"y":-15.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"TEXT","characters":"Information Systems","style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":{"fontColor":{"a":1.0,"b":1.0,"g":1.0,"r":1.0},"weight":"400"},"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"characterStyleOverrides":[],"styleOverrideTable":{},"pbdfType":null,"attributedString":null,"automaticallyDrawOnUnderlyingPath":null,"dontSynchroniseWithSymbol":null,"glyphBounds":null,"lineSpacingBehaviour":null,"textBehaviour":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null},{"id":"41:121","name":"Buttons / Round / 32px Icon Button","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":-20.0},"transitionNodeID":null,"children":[{"id":"41:122","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":-20.0},"transitionNodeID":null,"children":[{"id":"41:123","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":1497.0,"y":-20.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":{"fill":"0:274"},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"41:158","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":1503.0,"y":-14.0},"transitionNodeID":null,"children":[{"id":"41:159","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":15.291667938232422,"width":16.666667938232422,"x":1504.6666259765625,"y":-11.5},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:56.png"},{"pbdfType":"screen","id":"0:54","name":"Icons / Love","convert":true,"type":null,"designNode":{"id":"0:54","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1371.0,"y":248.0},"transitionNodeID":null,"children":[{"id":"0:55","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.350000381469727,"width":20.0,"x":1373.0,"y":251.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.40784314274787903,"g":0.40784314274787903,"b":0.40784314274787903,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:54.png"},{"pbdfType":"screen","id":"0:52","name":"Icons / Love","convert":true,"type":null,"designNode":{"id":"0:52","name":"Icons / Love","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1371.0,"y":124.0},"transitionNodeID":null,"children":[{"id":"0:53","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":18.350000381469727,"width":20.0,"x":1373.0,"y":127.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":1.0,"b":0.9998798966407776,"g":1.0,"r":0.9999018311500549},"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:52.png"},{"pbdfType":"screen","id":"0:48","name":"Buttons / Round / 2. Secondary / 32px","convert":true,"type":null,"designNode":{"id":"0:48","name":"Buttons / Round / 2. Secondary / 32px","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":100.0,"y":396.0},"transitionNodeID":null,"children":[{"id":"0:49","name":"Info","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":100.0,"y":396.0},"transitionNodeID":null,"children":[{"id":"0:50","name":"⬛ Background","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":100.0,"y":396.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.9474354386329651,"g":0.9474354386329651,"b":0.9474354386329651,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:51","name":"🧡 Icon","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":106.0,"y":402.0},"transitionNodeID":null,"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"CENTER","horizontal":"CENTER"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[],"imageReference":null,"isFlowHome":null,"type":"INSTANCE","parameters":null,"symbolID":null,"children":[{"id":"I0:51;0:47","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":20.0,"width":20.0,"x":106.0,"y":402.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.6705729365348816,"g":0.6705729365348816,"b":0.6705729365348816,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"componentId":"0:46","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"type":"FRAME","fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"pbdfType":null,"isFlowHome":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:48.png"},{"pbdfType":"screen","id":"0:46","name":"Icons / Icon Area","convert":true,"type":null,"designNode":{"id":"0:46","name":"Icons / Icon Area","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1371.0,"y":-72.0},"transitionNodeID":null,"children":[{"id":"0:47","name":"🔷 Icon Color","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":1371.0,"y":-72.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.6705729365348816,"g":0.6705729365348816,"b":0.6705729365348816,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.9999018311500549,"g":1.0,"b":0.9998798966407776,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:46.png"},{"pbdfType":"screen","id":"0:38","name":"person/12","convert":true,"type":null,"designNode":{"id":"0:38","name":"person/12","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":846.0},"transitionNodeID":null,"children":[{"id":"0:39","name":"Group 7","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":846.0},"transitionNodeID":null,"children":[{"id":"0:40","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":846.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:42","name":"images (2)","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":63.0,"x":1212.0,"y":846.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"762e6bf5275df04d86809d5558393e736b689df2","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:38.png"},{"pbdfType":"screen","id":"0:33","name":"person/5","convert":true,"type":null,"designNode":{"id":"0:33","name":"person/5","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":705.0},"transitionNodeID":null,"children":[{"id":"0:34","name":"Group 8","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":705.0},"transitionNodeID":null,"children":[{"id":"0:35","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":705.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:37","name":"mens-slicked-back-grey-hair","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":47.0,"width":47.0,"x":1227.0,"y":705.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"466b9d7e969ee5eae4fa60480890a3c382b99131","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:33.png"},{"pbdfType":"screen","id":"0:28","name":"person/1","convert":true,"type":null,"designNode":{"id":"0:28","name":"person/1","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":564.0},"transitionNodeID":null,"children":[{"id":"0:29","name":"Group 4 Copy 3","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":564.0},"transitionNodeID":null,"children":[{"id":"0:30","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":564.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:32","name":"bearded-men-face-hipster-character-vector-14648253","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":43.0,"width":29.0,"x":1236.0,"y":566.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"fa88d58c5f0e4e19ea1f1da0bc095f753c04260c","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:28.png"},{"pbdfType":"screen","id":"0:20","name":"person/4","convert":true,"type":null,"designNode":{"id":"0:20","name":"person/4","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":282.0},"transitionNodeID":null,"children":[{"id":"0:21","name":"Group 7","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":282.0},"transitionNodeID":null,"children":[{"id":"0:22","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":282.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:24","name":"MV5BMTc0MzY2NjE0Nl5BMl5BanBnXkFtZTYwMDkxMDY0._V1_UY256_CR4,0,172,256_AL_","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":62.0,"width":41.0,"x":1230.0,"y":282.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"da827996130fb49beae52d638023a3c521add634","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:20.png"},{"pbdfType":"screen","id":"0:15","name":"person/8","convert":true,"type":null,"designNode":{"id":"0:15","name":"person/8","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":141.0},"transitionNodeID":null,"children":[{"id":"0:16","name":"Group 9 Copy","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":141.0},"transitionNodeID":null,"children":[{"id":"0:17","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":141.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:19","name":"download","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":42.0,"width":42.0,"x":1229.0,"y":141.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"0ee38c205bd2ebee137b0ff0ba528cf791c37df6","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:15.png"},{"pbdfType":"screen","id":"0:10","name":"person/6","convert":true,"type":null,"designNode":{"id":"0:10","name":"person/6","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":0.0},"transitionNodeID":null,"children":[{"id":"0:11","name":"Group 11","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":0.0},"transitionNodeID":null,"children":[{"id":"0:12","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":41.0,"width":41.0,"x":1230.0,"y":0.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"opacity":0.06165081635117531,"blendMode":"NORMAL","type":"SOLID","color":{"r":0.0,"g":0.0,"b":0.0,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:14","name":"MV5BMjAwMzc5OTEzOF5BMl5BanBnXkFtZTgwMDc5ODU3MTE@._V1_UX172_CR0,0,172,256_AL_","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":null,"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":1.0,"color":null,"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":61.0,"width":41.0,"x":1230.0,"y":0.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"IMAGE","scaleMode":"STRETCH","imageRef":"d3bd9ca71b3fe97e05ddf694a700390c236d4c38","imageTransform":[[1.0,0.0,0.0],[0.0,1.0,0.0]]}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":null,"rectangleCornerRadii":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"isFlowHome":null,"type":"GROUP","imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:10.png"},{"pbdfType":"screen","id":"0:2","name":"icons/tab bar/home","convert":true,"type":null,"designNode":{"id":"0:2","name":"icons/tab bar/home","pluginData":null,"sharedPluginData":null,"visible":true,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":32.0,"width":32.0,"x":100.0,"y":264.0},"transitionNodeID":null,"children":[{"id":"0:3","name":"Oval","pluginData":null,"sharedPluginData":null,"visible":false,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":24.0,"width":24.0,"x":104.0,"y":268.0},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.847000002861023,"g":0.847000002861023,"b":0.847000002861023,"a":1.0}}],"imageReference":null,"type":"ELLIPSE","pbdfType":null},{"id":"0:8","name":"Shape","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5329999923706055,"g":0.5661500096321106,"b":0.6499999761581421,"a":1.0}}],"children":[{"id":"0:6","name":"Subtract","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"TOP","horizontal":"LEFT"},"transitionNodeID":null,"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.8549019694328308,"g":0.8549019694328308,"b":0.8549019694328308,"a":1.0}}],"children":[{"id":"0:4","name":"Path","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":12.44444465637207,"width":23.33333396911621,"x":104.0,"y":270.0},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[],"imageReference":null,"pbdfType":null},{"id":"0:5","name":"Rectangle","pluginData":null,"sharedPluginData":null,"visible":true,"style":{"backgroundColor":null,"fills":[{"color":{"a":1.0,"b":0.6499999761581421,"g":0.578499972820282,"r":0.5525000095367432},"isEnabled":true}],"borders":[{"isEnabled":false,"fillType":null,"color":{"a":1.0,"b":0.5920000076293945,"g":0.5920000076293945,"r":0.5920000076293945},"thickness":0.0}],"textStyle":null,"borderOptions":{"dashPattern":null,"isEnabled":false,"lineCapStyle":null,"lineJoinStyle":null}},"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":5.689725875854492,"width":8.836241722106934,"x":116.1908950805664,"y":274.412353515625},"size":null,"strokes":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":0.5920000076293945,"g":0.5920000076293945,"b":0.5920000076293945,"a":1.0}}],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"fills":[{"blendMode":"NORMAL","type":"SOLID","color":{"r":0.5525000095367432,"g":0.578499972820282,"b":0.6499999761581421,"a":1.0}}],"imageReference":null,"type":"RECTANGLE","points":null,"cornerRadius":0.8999999761581421,"rectangleCornerRadii":null,"pbdfType":null}],"booleanOperation":null,"type":"BOOLEAN_OPERATION","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":100.0,"width":100.0,"x":104.0,"y":270.0},"imageReference":null,"pbdfType":null},{"id":"0:7","name":"Path","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":12.169487953186035,"width":3.1111111640930176,"x":124.22222137451172,"y":278.83050537109375},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[],"imageReference":null,"pbdfType":null},{"id":"0:9","name":"Path","pluginData":null,"sharedPluginData":null,"visible":true,"style":null,"layoutAlign":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"transitionNodeID":null,"absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":7.115451812744141,"width":14.0,"x":108.66666412353516,"y":280.7734375},"size":null,"strokes":[],"strokeWeight":0.0,"strokeAlign":"CENTER","styles":null,"type":"VECTOR","fills":[],"imageReference":null,"pbdfType":null}],"booleanOperation":null,"type":"BOOLEAN_OPERATION","absoluteBoundingBox":{"_class":null,"constrainProportions":null,"height":21.0,"width":23.33333396911621,"x":104.0,"y":270.0},"imageReference":null,"pbdfType":null}],"strokes":[],"strokeWeight":1.0,"strokeAlign":"INSIDE","cornerRadius":null,"constraints":{"vertical":"SCALE","horizontal":"SCALE"},"layoutAlign":null,"size":null,"horizontalPadding":null,"verticalPadding":null,"itemSpacing":null,"backgroundColor":{"a":0.0,"b":0.0,"g":0.0,"r":0.0},"fills":[{"blendMode":"NORMAL","visible":false,"type":"SOLID","color":{"r":1.0,"g":1.0,"b":1.0,"a":1.0}}],"imageReference":null,"type":"COMPONENT","overrideProperties":null,"overriadableProperties":null,"symbolID":null,"pbdfType":null,"isFlowHome":null},"azure_blob_uri":"/0:2.png"}]}],"miscPages":[],"azure_container_uri":""} \ No newline at end of file From 2350c1d5b24656579e3ed405be73794827d90409 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 30 Apr 2021 17:32:33 -0600 Subject: [PATCH 010/404] Call cleanTreeParity method --- lib/controllers/interpret.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 6a116419..261364ad 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -65,6 +65,8 @@ class Interpret { } } + _pb_project.cleanTreeParity(); + return _pb_project; } @@ -81,7 +83,8 @@ class Interpret { tempTree.data = PBGenerationViewData(); if (currentScreen.rootNode is InheritedScaffold) { - PBPlatformOrientationLinkerService().addOrientationPlatformInformation(tempTree); + PBPlatformOrientationLinkerService() + .addOrientationPlatformInformation(tempTree); } else if (currentScreen.rootNode is PBSharedMasterNode) { tempTree.tree_type = TREE_TYPE.VIEW; } else { From 23062f87b077767fca85b7683aef8c99a713b9bb Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 30 Apr 2021 17:33:16 -0600 Subject: [PATCH 011/404] Implemented cleanTreeParity to avoid duplicated names --- .../helpers/pb_project.dart | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index 045e1332..f18a1320 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -25,4 +25,41 @@ class PBProject { _genProjectData = PBGenerationProjectData(); _fileStructureStrategy = fileStructureStrategy; } + + // Pass through the forest once checking all trees + // if two or more trees have the same name and same + // orientation, a `_n` counter is added at the end + // of their name + void cleanTreeParity() { + forest.sort((a, b) => a.rootNode.name.compareTo(b.rootNode.name)); + var currentCounter = 0; + var nextCounter = currentCounter + 1; + var nameCounter = 1; + + while (nextCounter < forest.length) { + var currentTree = forest[currentCounter]; + var nextTree = forest[nextCounter]; + if (currentTree.rootNode.name.compareTo(nextTree.rootNode.name) == 0) { + if (currentTree.data.orientation == nextTree.data.orientation) { + forest[nextCounter].rootNode.name = + forest[nextCounter].rootNode.name + '_$nameCounter'; + + nameCounter++; + nextCounter++; + } else { + currentCounter++; + if (currentCounter >= nextCounter) { + nextCounter++; + } + } + } else { + currentCounter++; + if (currentCounter >= nextCounter) { + nextCounter++; + } + nameCounter = 1; + } + } + print('hello'); + } } From ca66fae1753761fe256741caa0d9b75200e104f2 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 30 Apr 2021 17:39:27 -0600 Subject: [PATCH 012/404] Removed unnecessary print statement --- lib/interpret_and_optimize/helpers/pb_project.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index f18a1320..921f0615 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -60,6 +60,5 @@ class PBProject { nameCounter = 1; } } - print('hello'); } } From 8d43850cee21a042a88111560d8c520b7ef4554a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 2 May 2021 11:36:53 -0600 Subject: [PATCH 013/404] Remove `.dart` from `file_structure_strategy` dir --- .../middleware/state_management/bloc_middleware.dart | 2 +- .../middleware/state_management/provider_middleware.dart | 2 +- .../middleware/state_management/riverpod_middleware.dart | 2 +- .../middleware/state_management/stateful_middleware.dart | 2 +- .../bloc_file_structure_strategy.dart | 2 +- .../flutter_file_structure_strategy.dart | 2 +- .../pb_file_structure_strategy.dart | 0 .../provider_file_structure_strategy.dart | 2 +- .../riverpod_file_structure_strategy.dart | 2 +- .../bloc_generation_configuration.dart | 2 +- .../generation_configuration/pb_generation_configuration.dart | 4 ++-- .../provider_generation_configuration.dart | 2 +- .../riverpod_generation_configuration.dart | 2 +- .../stateful_generation_configuration.dart | 2 +- lib/interpret_and_optimize/helpers/pb_project.dart | 2 +- test/lib/middleware/bloc_test.dart | 2 +- test/lib/middleware/provider_test.dart | 2 +- test/lib/middleware/stateful_test.dart | 2 +- test/lib/output_services/project_builder_test.dart | 4 ++-- 19 files changed, 20 insertions(+), 20 deletions(-) rename lib/generation/generators/value_objects/{file_structure_strategy.dart => file_structure_strategy}/bloc_file_structure_strategy.dart (87%) rename lib/generation/generators/value_objects/{file_structure_strategy.dart => file_structure_strategy}/flutter_file_structure_strategy.dart (87%) rename lib/generation/generators/value_objects/{file_structure_strategy.dart => file_structure_strategy}/pb_file_structure_strategy.dart (100%) rename lib/generation/generators/value_objects/{file_structure_strategy.dart => file_structure_strategy}/provider_file_structure_strategy.dart (95%) rename lib/generation/generators/value_objects/{file_structure_strategy.dart => file_structure_strategy}/riverpod_file_structure_strategy.dart (95%) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index ba428645..287596ae 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/generation/generators/pb_variable.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 6151a5bf..73d03880 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -3,7 +3,7 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index b3279294..e5527cc7 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 492f69f9..ef394b38 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -1,6 +1,6 @@ import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/bloc_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart similarity index 87% rename from lib/generation/generators/value_objects/file_structure_strategy.dart/bloc_file_structure_strategy.dart rename to lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart index cd58225e..0631d09a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/bloc_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart @@ -1,4 +1,4 @@ -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart similarity index 87% rename from lib/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart rename to lib/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart index cde8f668..246306e5 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; class FlutterFileStructureStrategy extends FileStructureStrategy { diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart similarity index 100% rename from lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart rename to lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart similarity index 95% rename from lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart rename to lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart index b65cd8ba..da402f5c 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; class ProviderFileStructureStrategy extends FileStructureStrategy { diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart similarity index 95% rename from lib/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart rename to lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart index e7cb449c..8620d23a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; diff --git a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart index 9e8b0898..fef20b43 100644 --- a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/bloc_middleware.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:quick_log/quick_log.dart'; diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index eaaa8d24..aee4dadb 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -6,8 +6,8 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; diff --git a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart index 476a567c..a0fded5b 100644 --- a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/provider_middleware.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; diff --git a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart index 407fffa5..767b95fd 100644 --- a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/riverpod_middleware.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; diff --git a/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart index 62f15bb0..ea22f7c0 100644 --- a/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/stateful_middleware.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; class StatefulGenerationConfiguration extends GenerationConfiguration { diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index 045e1332..ef32e8f0 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; diff --git a/test/lib/middleware/bloc_test.dart b/test/lib/middleware/bloc_test.dart index 241f22da..507152f9 100644 --- a/test/lib/middleware/bloc_test.dart +++ b/test/lib/middleware/bloc_test.dart @@ -6,7 +6,7 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; diff --git a/test/lib/middleware/provider_test.dart b/test/lib/middleware/provider_test.dart index 5a8552fd..6a7cc9fa 100644 --- a/test/lib/middleware/provider_test.dart +++ b/test/lib/middleware/provider_test.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; diff --git a/test/lib/middleware/stateful_test.dart b/test/lib/middleware/stateful_test.dart index f4fb3ab0..46b14e7e 100644 --- a/test/lib/middleware/stateful_test.dart +++ b/test/lib/middleware/stateful_test.dart @@ -6,7 +6,7 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index 02bf16a8..dd97e6ac 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -3,8 +3,8 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; From a2a4a0c4e87ca34cc55df738114d7c04f5964b3a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 2 May 2021 11:46:08 -0600 Subject: [PATCH 014/404] Create abstract FileStructureCommand --- .../commands/file_structure_command.dart | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart new file mode 100644 index 00000000..f433e488 --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart @@ -0,0 +1,5 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; + +abstract class FileStructureCommand { + Future write(FileStructureStrategy strategy); +} From be531d6c3ca926f07b9fb0943f4d15ef13b81934 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 2 May 2021 12:04:22 -0600 Subject: [PATCH 015/404] Create `AddConstantCommand` class --- .../commands/add_constant_command.dart | 18 ++++++++++++++++++ .../pb_file_structure_strategy.dart | 4 ++++ 2 files changed, 22 insertions(+) create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart new file mode 100644 index 00000000..c68d20b4 --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -0,0 +1,18 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; + +class AddConstantCommand implements FileStructureCommand { + String name; + String type; + String value; + + AddConstantCommand(this.name, this.type, this.value); + + @override + Future write(FileStructureStrategy strategy) { + var constantStr = 'const $type $name = $value'; + var path = '${strategy.GENERATED_PROJECT_PATH}/${strategy.RELATIVE_CONSTANT_PATH}/constants.dart'; + //TODO: validate adding a method to pageWriter to `append` to a file rather than completely overwriting it. + strategy.pageWriter.write(constantStr, path); + } +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index c09cbfb7..71c9c24c 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -21,6 +21,10 @@ abstract class FileStructureStrategy { ///The path of where all the screens are going to be generated. final RELATIVE_SCREEN_PATH = 'lib/screens/'; + /// Path where all files containing constants will be generated + final RELATIVE_CONSTANT_PATH = + 'lib/constants/'; //TODO: validate adding this new path + Logger logger; ///Path of where the project is generated From a7019f582ccf87c22188f5159aa85f7b92ad451a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 2 May 2021 12:22:45 -0600 Subject: [PATCH 016/404] Add incomplete command classes The classes are for adding dependencies, screens, and symbols. --- .../commands/add_dependency_command.dart | 17 +++++++++++++++++ .../commands/write_screen_command.dart | 16 ++++++++++++++++ .../commands/write_symbol_command.dart | 15 +++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart new file mode 100644 index 00000000..c86d5a82 --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -0,0 +1,17 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; + +class AddDependencyCommand implements FileStructureCommand { + String package; + String type; + String value; + + AddDependencyCommand(this.package, this.type, this.value); + + @override + Future write(FileStructureStrategy strategy) { + + // TODO: implement write + throw UnimplementedError(); + } +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart new file mode 100644 index 00000000..b1de1f1a --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -0,0 +1,16 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; + +class WriteScreenCommand implements FileStructureCommand { + String name; + String path; + String value; + + WriteScreenCommand(this.name, this.path, this.value); + + @override + Future write(FileStructureStrategy strategy) { + // TODO: implement write + throw UnimplementedError(); + } +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart new file mode 100644 index 00000000..eb5df01c --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -0,0 +1,15 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; + +class WriteSymbolCommand implements FileStructureCommand { + String name; + String data; + + WriteSymbolCommand(this.name, this.data); + + @override + Future write(FileStructureStrategy strategy) { + // TODO: implement write + throw UnimplementedError(); + } +} From c5b9f787e6ab5a8d56e806dfbbb9859fa08f12aa Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 2 May 2021 16:55:15 -0600 Subject: [PATCH 017/404] Added method to FileWriter to append to a file. --- .../generators/writers/pb_flutter_writer.dart | 11 +++++++++++ lib/generation/generators/writers/pb_page_writer.dart | 2 ++ .../writers/pb_traversal_adapter_writer.dart | 8 +++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index 0fabd606..2139f00b 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -24,6 +24,17 @@ class PBFlutterWriter implements PBPageWriter { writer.writeAsStringSync(code); } + /// Appends [code] to the end of file located at [fileAbsPath]. + /// + /// Does nothing if the file at [fileAbsPath] does not exist. + @override + void append(String code, String fileAbsPath) { + var file = File(fileAbsPath); + if (file.existsSync()) { + file.writeAsStringSync(code, mode: FileMode.append); + } + } + /// Function that allows the rewriting of the main() method inside main.dart void rewriteMainFunction(String pathToMain, String code, {Set imports}) { diff --git a/lib/generation/generators/writers/pb_page_writer.dart b/lib/generation/generators/writers/pb_page_writer.dart index 60293e02..b424e1d5 100644 --- a/lib/generation/generators/writers/pb_page_writer.dart +++ b/lib/generation/generators/writers/pb_page_writer.dart @@ -2,5 +2,7 @@ abstract class PBPageWriter { Map dependencies = {}; void write(String code, String fileName); + void append(String code, String fileName); + void addDependency(String packageName, String version); } diff --git a/lib/generation/generators/writers/pb_traversal_adapter_writer.dart b/lib/generation/generators/writers/pb_traversal_adapter_writer.dart index 67987ac4..0a68eb43 100644 --- a/lib/generation/generators/writers/pb_traversal_adapter_writer.dart +++ b/lib/generation/generators/writers/pb_traversal_adapter_writer.dart @@ -3,7 +3,8 @@ import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart' /// Adapter used to traverse trees using generation /// without actually writing to the tree itself. /// -/// TODO: add more detail to purpose of empty methods. +/// The adapter's purpose is to disregard requests to modify any files, +/// hence the empty return methods. class PBTraversalAdapterWriter extends PBPageWriter { @override void addDependency(String packageName, String version) { @@ -14,4 +15,9 @@ class PBTraversalAdapterWriter extends PBPageWriter { void write(String code, String fileName) { return; } + + @override + void append(String code, String fileName) { + return; + } } From 7a23dd0ca7974b0f5faf02f2c278e9ab0285ef9a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 2 May 2021 16:56:46 -0600 Subject: [PATCH 018/404] Moved CONST_PATH to AddConstantCommand. This path was previously in FileStructureStrategy, but was moved to give that responsibility to the AddConstantCommand. --- .../commands/add_constant_command.dart | 6 +++--- .../file_structure_strategy/pb_file_structure_strategy.dart | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index c68d20b4..aa81245c 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -5,14 +5,14 @@ class AddConstantCommand implements FileStructureCommand { String name; String type; String value; + final String CONST_PATH = 'lib/constants/constants.dart'; AddConstantCommand(this.name, this.type, this.value); @override Future write(FileStructureStrategy strategy) { - var constantStr = 'const $type $name = $value'; - var path = '${strategy.GENERATED_PROJECT_PATH}/${strategy.RELATIVE_CONSTANT_PATH}/constants.dart'; - //TODO: validate adding a method to pageWriter to `append` to a file rather than completely overwriting it. + var constantStr = 'const $type $name = $value;'; + var path = '${strategy.GENERATED_PROJECT_PATH}/${CONST_PATH}'; strategy.pageWriter.write(constantStr, path); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 71c9c24c..c09cbfb7 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -21,10 +21,6 @@ abstract class FileStructureStrategy { ///The path of where all the screens are going to be generated. final RELATIVE_SCREEN_PATH = 'lib/screens/'; - /// Path where all files containing constants will be generated - final RELATIVE_CONSTANT_PATH = - 'lib/constants/'; //TODO: validate adding this new path - Logger logger; ///Path of where the project is generated From c16311d6f51b2c2c0071c03f62152e523d8e6b35 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 2 May 2021 16:59:20 -0600 Subject: [PATCH 019/404] Populate write() method of AddDependency command --- .../commands/add_dependency_command.dart | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart index c86d5a82..108bcf56 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -3,15 +3,12 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure class AddDependencyCommand implements FileStructureCommand { String package; - String type; - String value; + String version; - AddDependencyCommand(this.package, this.type, this.value); + AddDependencyCommand(this.package, this.version); @override Future write(FileStructureStrategy strategy) { - - // TODO: implement write - throw UnimplementedError(); + strategy.pageWriter.addDependency(package, version); } } From e2cfaf59287a1c40f08fbbd814cf75f34c0a65fb Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 2 May 2021 17:06:15 -0600 Subject: [PATCH 020/404] Populate write() method of WriteScreenCommand --- .../commands/write_screen_command.dart | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index b1de1f1a..cf6c14ab 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -3,14 +3,21 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure class WriteScreenCommand implements FileStructureCommand { String name; - String path; - String value; + String relativePath; + String data; - WriteScreenCommand(this.name, this.path, this.value); + final SCREEN_PATH = 'lib/modules'; + WriteScreenCommand(this.name, this.relativePath, this.data); + + /// Writes a file containing [data] to [path] with [name] as its filename. + /// + /// Returns path to screen that was created. @override Future write(FileStructureStrategy strategy) { - // TODO: implement write - throw UnimplementedError(); + var absPath = + '${strategy.GENERATED_PROJECT_PATH}/$SCREEN_PATH/$relativePath/$name'; + strategy.pageWriter.write(data, absPath); + return Future.value(absPath); } } From 7ed510d1c1482c7b176301787bcacf7d4ed1ab14 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 2 May 2021 17:08:54 -0600 Subject: [PATCH 021/404] Populate write() method of WriteSymbolCommand --- .../commands/write_screen_command.dart | 4 ++-- .../commands/write_symbol_command.dart | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index cf6c14ab..0056e828 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -10,9 +10,9 @@ class WriteScreenCommand implements FileStructureCommand { WriteScreenCommand(this.name, this.relativePath, this.data); - /// Writes a file containing [data] to [path] with [name] as its filename. + /// Writes a screen file containing [data] to [path] with [name] as its filename. /// - /// Returns path to screen that was created. + /// Returns path to the file that was created. @override Future write(FileStructureStrategy strategy) { var absPath = diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index eb5df01c..59ec5b3c 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -4,12 +4,17 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure class WriteSymbolCommand implements FileStructureCommand { String name; String data; + final String SYMBOL_PATH = 'lib/widgets'; WriteSymbolCommand(this.name, this.data); + /// Writes a symbol file containing [data] with [name] as its filename. + /// + /// Returns path to the file that was created. @override Future write(FileStructureStrategy strategy) { - // TODO: implement write - throw UnimplementedError(); + var absPath = '${strategy.GENERATED_PROJECT_PATH}/$SYMBOL_PATH/$name'; + strategy.pageWriter.write(data, absPath); + return Future.value(absPath); } } From 2554ce5f6f09abbb901e292b8a914239b8aa31db Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 3 May 2021 16:03:15 -0600 Subject: [PATCH 022/404] Removed trailing `/` from strategy project path --- .../file_structure_strategy/commands/add_constant_command.dart | 2 +- .../file_structure_strategy/commands/write_screen_command.dart | 2 +- .../file_structure_strategy/commands/write_symbol_command.dart | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index aa81245c..d8543ba1 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -12,7 +12,7 @@ class AddConstantCommand implements FileStructureCommand { @override Future write(FileStructureStrategy strategy) { var constantStr = 'const $type $name = $value;'; - var path = '${strategy.GENERATED_PROJECT_PATH}/${CONST_PATH}'; + var path = '${strategy.GENERATED_PROJECT_PATH}${CONST_PATH}'; strategy.pageWriter.write(constantStr, path); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 0056e828..fbf65817 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -16,7 +16,7 @@ class WriteScreenCommand implements FileStructureCommand { @override Future write(FileStructureStrategy strategy) { var absPath = - '${strategy.GENERATED_PROJECT_PATH}/$SCREEN_PATH/$relativePath/$name'; + '${strategy.GENERATED_PROJECT_PATH}$SCREEN_PATH/$relativePath/$name'; strategy.pageWriter.write(data, absPath); return Future.value(absPath); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 59ec5b3c..5f3196f8 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -13,7 +13,7 @@ class WriteSymbolCommand implements FileStructureCommand { /// Returns path to the file that was created. @override Future write(FileStructureStrategy strategy) { - var absPath = '${strategy.GENERATED_PROJECT_PATH}/$SYMBOL_PATH/$name'; + var absPath = '${strategy.GENERATED_PROJECT_PATH}$SYMBOL_PATH/$name'; strategy.pageWriter.write(data, absPath); return Future.value(absPath); } From 182dee6576ac2283eec278eccd85c2e158934280 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 3 May 2021 16:24:21 -0600 Subject: [PATCH 023/404] append() creates file if it does not exist --- lib/generation/generators/writers/pb_flutter_writer.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index 2139f00b..6036da4d 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -26,12 +26,14 @@ class PBFlutterWriter implements PBPageWriter { /// Appends [code] to the end of file located at [fileAbsPath]. /// - /// Does nothing if the file at [fileAbsPath] does not exist. + /// Creates the file if the file at [fileAbsPath] does not exist. @override void append(String code, String fileAbsPath) { var file = File(fileAbsPath); if (file.existsSync()) { file.writeAsStringSync(code, mode: FileMode.append); + } else { + write(code, fileAbsPath); } } From 203096a780962d9d032e38d675df8a2202ff08fd Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 3 May 2021 16:25:32 -0600 Subject: [PATCH 024/404] AddConstantCommand calls writer's append() method This is done to prevent overwriting the file every time a constant is added. --- .../file_structure_strategy/commands/add_constant_command.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index d8543ba1..b1f659bb 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -13,6 +13,6 @@ class AddConstantCommand implements FileStructureCommand { Future write(FileStructureStrategy strategy) { var constantStr = 'const $type $name = $value;'; var path = '${strategy.GENERATED_PROJECT_PATH}${CONST_PATH}'; - strategy.pageWriter.write(constantStr, path); + strategy.pageWriter.append(constantStr, path); } } From 365d8024629615a17148760de24cf4704bf7e2e1 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 3 May 2021 17:19:28 -0600 Subject: [PATCH 025/404] Added file writer observer --- .../flutter_project_builder/file_writer_observer.dart | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 lib/generation/flutter_project_builder/file_writer_observer.dart diff --git a/lib/generation/flutter_project_builder/file_writer_observer.dart b/lib/generation/flutter_project_builder/file_writer_observer.dart new file mode 100644 index 00000000..46b3d1a3 --- /dev/null +++ b/lib/generation/flutter_project_builder/file_writer_observer.dart @@ -0,0 +1,3 @@ +abstract class FileWriterObserver { + void fileCreated(String filePath, String fileUUID); +} From 91c1972395264e085a99f85aff8a88026a395fec Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 3 May 2021 17:19:42 -0600 Subject: [PATCH 026/404] Implement new observer --- .../import_helper.dart | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 12b529f0..6ee51d0c 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -6,14 +6,17 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/file_writer_observer.dart'; + +class ImportHelper implements FileWriterObserver { + Map imports = {}; -class ImportHelper { /// Traverse the [node] tree, check if any nodes need importing, /// and add the relative import from [path] to the [node] static Set findImports(PBIntermediateNode node, String path) { - Set imports = {}; + Set currentImports = {}; if (node == null) { - return imports; + return currentImports; } String id; @@ -31,29 +34,34 @@ class ImportHelper { nodePaths.isNotEmpty && !nodePaths.any((element) => element == path)) { var paths = PBGenCache().getRelativePath(path, id); - paths.forEach(imports.add); + paths.forEach(currentImports.add); } // Recurse through child/children and add to imports if (node is PBLayoutIntermediateNode) { node.children - .forEach((child) => imports.addAll(findImports(child, path))); + .forEach((child) => currentImports.addAll(findImports(child, path))); } else if (node is InheritedScaffold) { - imports.addAll(findImports(node.navbar, path)); - imports.addAll(findImports(node.tabbar, path)); - imports.addAll(findImports(node.child, path)); + currentImports.addAll(findImports(node.navbar, path)); + currentImports.addAll(findImports(node.tabbar, path)); + currentImports.addAll(findImports(node.child, path)); } else if (node is InjectedAppbar) { - imports.addAll(findImports(node.leadingItem, path)); - imports.addAll(findImports(node.middleItem, path)); - imports.addAll(findImports(node.trailingItem, path)); + currentImports.addAll(findImports(node.leadingItem, path)); + currentImports.addAll(findImports(node.middleItem, path)); + currentImports.addAll(findImports(node.trailingItem, path)); } else if (node is InjectedTabBar) { for (var tab in node.tabs) { - imports.addAll(findImports(tab, path)); + currentImports.addAll(findImports(tab, path)); } } else { - imports.addAll(findImports(node.child, path)); + currentImports.addAll(findImports(node.child, path)); } - return imports; + return currentImports; + } + + @override + void fileCreated(String filePath, String fileUUID) { + imports[fileUUID] = filePath; } } From 37bd2351f1ee35896eaf7515dbcf69d09ca15a2a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 3 May 2021 17:55:05 -0600 Subject: [PATCH 027/404] Create AddConstantCommand unit test. --- .../commands/add_constant_command_test.dart | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/lib/generation/commands/add_constant_command_test.dart diff --git a/test/lib/generation/commands/add_constant_command_test.dart b/test/lib/generation/commands/add_constant_command_test.dart new file mode 100644 index 00000000..6f5ffe52 --- /dev/null +++ b/test/lib/generation/commands/add_constant_command_test.dart @@ -0,0 +1,40 @@ +import 'dart:io'; + +import 'package:mockito/mockito.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; +import 'package:test/test.dart'; + +class MockFSStrategy extends Mock implements FileStructureStrategy {} + +void main() { + final path = '${Directory.current.path}/test/lib/generation/commands/'; + group('Add Constant Command', () { + var strategy = MockFSStrategy(); + FileStructureCommand const1; + FileStructureCommand const2; + setUp(() { + // Create temporary directory to output files + Process.runSync('mkdir', ['tmptst'], workingDirectory: path); + + const1 = AddConstantCommand('c1', 'String', '\'test\''); + const2 = AddConstantCommand('c2', 'int', '20'); + when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); + when(strategy.pageWriter).thenReturn(PBFlutterWriter()); + }); + test('Testing Adding Constants To Project', () { + final constPath = '${path}tmptst/lib/constants/constants.dart'; + const1.write(strategy); + const2.write(strategy); + expect(File(constPath).existsSync(), true); + var constFile = File(constPath).readAsStringSync(); + expect(constFile.contains('const String c1 = \'test\''), true); + expect(constFile.contains('const int c2 = 20'), true); + }); + tearDownAll(() { + Process.runSync('rm', ['-r', 'tmptst'], workingDirectory: path); + }); + }); +} From 95cd55e877a55ed5b97f41e04388121a88457076 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 3 May 2021 18:04:40 -0600 Subject: [PATCH 028/404] Create AddDependencyCommand Unit Test --- .../commands/add_constant_command_test.dart | 3 +- .../commands/add_dependency_command_test.dart | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/lib/generation/commands/add_dependency_command_test.dart diff --git a/test/lib/generation/commands/add_constant_command_test.dart b/test/lib/generation/commands/add_constant_command_test.dart index 6f5ffe52..78a2dbd5 100644 --- a/test/lib/generation/commands/add_constant_command_test.dart +++ b/test/lib/generation/commands/add_constant_command_test.dart @@ -12,13 +12,14 @@ class MockFSStrategy extends Mock implements FileStructureStrategy {} void main() { final path = '${Directory.current.path}/test/lib/generation/commands/'; group('Add Constant Command', () { - var strategy = MockFSStrategy(); + var strategy; FileStructureCommand const1; FileStructureCommand const2; setUp(() { // Create temporary directory to output files Process.runSync('mkdir', ['tmptst'], workingDirectory: path); + strategy = MockFSStrategy(); const1 = AddConstantCommand('c1', 'String', '\'test\''); const2 = AddConstantCommand('c2', 'int', '20'); when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); diff --git a/test/lib/generation/commands/add_dependency_command_test.dart b/test/lib/generation/commands/add_dependency_command_test.dart new file mode 100644 index 00000000..5a92d7b6 --- /dev/null +++ b/test/lib/generation/commands/add_dependency_command_test.dart @@ -0,0 +1,33 @@ +import 'dart:io'; + +import 'package:mockito/mockito.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; +import 'package:test/test.dart'; + +class MockFSStrategy extends Mock implements FileStructureStrategy {} + +void main() { + final path = '${Directory.current.path}/test/lib/generation/commands/'; + group('Add Dependency Command', () { + FileStructureCommand command; + FileStructureStrategy strategy; + + setUp(() { + command = AddDependencyCommand('auto_size_text', '^2.1.0'); + strategy = MockFSStrategy(); + when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); + when(strategy.pageWriter).thenReturn(PBFlutterWriter()); + }); + + test('Testing adding a dependency', () { + command.write(strategy); + var dependencies = strategy.pageWriter.dependencies; + expect(dependencies.isNotEmpty, true); + expect(dependencies.containsKey('auto_size_text'), true); + expect(dependencies['auto_size_text'], '^2.1.0'); + }); + }); +} From ece5064bce7815cc3a7250af1fe3ef5fb8647f0e Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 3 May 2021 18:21:30 -0600 Subject: [PATCH 029/404] Create WriteScreenCommand Unit Test --- .../commands/write_screen_command_test.dart | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 test/lib/generation/commands/write_screen_command_test.dart diff --git a/test/lib/generation/commands/write_screen_command_test.dart b/test/lib/generation/commands/write_screen_command_test.dart new file mode 100644 index 00000000..00c19da9 --- /dev/null +++ b/test/lib/generation/commands/write_screen_command_test.dart @@ -0,0 +1,61 @@ +import 'dart:io'; + +import 'package:mockito/mockito.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; +import 'package:test/test.dart'; + +class MockFSStrategy extends Mock implements FileStructureStrategy {} + +void main() { + final path = '${Directory.current.path}/test/lib/generation/commands/'; + final screenData = ''' + import 'package:flutter/material.dart'; + + class TestScreen extends StatefulWidget { + const TestScreen() : super(); + @override + _TestScreen createState() => _TestScreen(); + } + + class _TestScreen extends State { + _TestScreen(); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container(), + ); + } + + @override + void dispose() { + super.dispose(); + } + } + '''; + group('Add Screen Command', () { + FileStructureCommand command; + FileStructureStrategy strategy; + + setUp(() { + command = WriteScreenCommand('test_screen.dart', 'screens', screenData); + strategy = MockFSStrategy(); + when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); + when(strategy.pageWriter).thenReturn(PBFlutterWriter()); + }); + + test('Testing writing a screen', () { + var screenPath = '${path}tmptst/lib/modules/screens/test_screen.dart'; + var screenFile = File(screenPath); + command.write(strategy); + expect(screenFile.existsSync(), true); + expect(screenFile.readAsStringSync().contains(screenData), true); + }); + tearDownAll(() { + Process.runSync('rm', ['-r', 'tmptst'], workingDirectory: path); + }); + }); +} From 6f4edb2ba05d943c348db92afb4efcd624931fb5 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 3 May 2021 18:25:23 -0600 Subject: [PATCH 030/404] Handle async for current command tests --- .../generation/commands/add_constant_command_test.dart | 6 +++--- .../generation/commands/add_dependency_command_test.dart | 4 ++-- .../generation/commands/write_screen_command_test.dart | 8 ++++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/test/lib/generation/commands/add_constant_command_test.dart b/test/lib/generation/commands/add_constant_command_test.dart index 78a2dbd5..a19480d3 100644 --- a/test/lib/generation/commands/add_constant_command_test.dart +++ b/test/lib/generation/commands/add_constant_command_test.dart @@ -25,10 +25,10 @@ void main() { when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); when(strategy.pageWriter).thenReturn(PBFlutterWriter()); }); - test('Testing Adding Constants To Project', () { + test('Testing Adding Constants To Project', () async { final constPath = '${path}tmptst/lib/constants/constants.dart'; - const1.write(strategy); - const2.write(strategy); + await const1.write(strategy); + await const2.write(strategy); expect(File(constPath).existsSync(), true); var constFile = File(constPath).readAsStringSync(); expect(constFile.contains('const String c1 = \'test\''), true); diff --git a/test/lib/generation/commands/add_dependency_command_test.dart b/test/lib/generation/commands/add_dependency_command_test.dart index 5a92d7b6..95b6592b 100644 --- a/test/lib/generation/commands/add_dependency_command_test.dart +++ b/test/lib/generation/commands/add_dependency_command_test.dart @@ -22,8 +22,8 @@ void main() { when(strategy.pageWriter).thenReturn(PBFlutterWriter()); }); - test('Testing adding a dependency', () { - command.write(strategy); + test('Testing adding a dependency', () async { + await command.write(strategy); var dependencies = strategy.pageWriter.dependencies; expect(dependencies.isNotEmpty, true); expect(dependencies.containsKey('auto_size_text'), true); diff --git a/test/lib/generation/commands/write_screen_command_test.dart b/test/lib/generation/commands/write_screen_command_test.dart index 00c19da9..55d6baf5 100644 --- a/test/lib/generation/commands/write_screen_command_test.dart +++ b/test/lib/generation/commands/write_screen_command_test.dart @@ -47,10 +47,14 @@ void main() { when(strategy.pageWriter).thenReturn(PBFlutterWriter()); }); - test('Testing writing a screen', () { + test('Testing writing a screen', () async { var screenPath = '${path}tmptst/lib/modules/screens/test_screen.dart'; var screenFile = File(screenPath); - command.write(strategy); + var commandPath = await command.write(strategy); + + // The return of WriteScreenCommand is `String` + // ignore: unrelated_type_equality_checks + expect(screenPath == commandPath, true); expect(screenFile.existsSync(), true); expect(screenFile.readAsStringSync().contains(screenData), true); }); From 8d7964ecbbf5fbd6872f43bfad49c5394b21e8f1 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 3 May 2021 18:31:06 -0600 Subject: [PATCH 031/404] Create WriteSymbolCommand Unit Test --- .../commands/write_symbol_command_test.dart | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 test/lib/generation/commands/write_symbol_command_test.dart diff --git a/test/lib/generation/commands/write_symbol_command_test.dart b/test/lib/generation/commands/write_symbol_command_test.dart new file mode 100644 index 00000000..1d789f80 --- /dev/null +++ b/test/lib/generation/commands/write_symbol_command_test.dart @@ -0,0 +1,59 @@ +import 'dart:io'; + +import 'package:mockito/mockito.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; +import 'package:test/test.dart'; + +class MockFSStrategy extends Mock implements FileStructureStrategy {} + +void main() { + final path = '${Directory.current.path}/test/lib/generation/commands/'; + final symData = ''' + import 'package:flutter/material.dart'; + + class TestSymbol extends State { + TestSymbol(); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container(), + ); + } + + @override + void dispose() { + super.dispose(); + } + } + '''; + group('Add Symbol Command', () { + FileStructureCommand command; + FileStructureStrategy strategy; + + setUp(() { + command = WriteSymbolCommand('test_symbol.dart', symData); + strategy = MockFSStrategy(); + when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); + when(strategy.pageWriter).thenReturn(PBFlutterWriter()); + }); + + test('Testing writing a symbol', () async { + var screenPath = '${path}tmptst/lib/widgets/test_symbol.dart'; + var screenFile = File(screenPath); + var commandPath = await command.write(strategy); + + // The return of WriteSymbolCommand is `String` + // ignore: unrelated_type_equality_checks + expect(screenPath == commandPath, true); + expect(screenFile.existsSync(), true); + expect(screenFile.readAsStringSync().contains(symData), true); + }); + tearDownAll(() { + Process.runSync('rm', ['-r', 'tmptst'], workingDirectory: path); + }); + }); +} From 4dbe0bfe370ebe0b922cf89df4b2f808cfd1beeb Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 4 May 2021 16:52:09 -0600 Subject: [PATCH 032/404] Instead of incrementing counter make it equal to the next counter --- lib/interpret_and_optimize/helpers/pb_project.dart | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index 921f0615..5b38865f 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -47,18 +47,15 @@ class PBProject { nameCounter++; nextCounter++; } else { - currentCounter++; - if (currentCounter >= nextCounter) { - nextCounter++; - } - } - } else { - currentCounter++; - if (currentCounter >= nextCounter) { + currentCounter = nextCounter; nextCounter++; } + } else { + currentCounter = nextCounter; + nextCounter++; nameCounter = 1; } } + print('stop'); } } From 9c87207dffb8ef17f6b3072ff296bb4dd1e9bf17 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 4 May 2021 17:14:46 -0600 Subject: [PATCH 033/404] Removed print statement --- lib/interpret_and_optimize/helpers/pb_project.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index 5b38865f..3b00d445 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -56,6 +56,5 @@ class PBProject { nameCounter = 1; } } - print('stop'); } } From 8fb4a50487b2a79d16cf59c6f9fcf6e084418d68 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 4 May 2021 19:07:10 -0600 Subject: [PATCH 034/404] Create extension NodeFileStructureCommand of FileStructureCommand This abstract class relies on `code` to execute its `write()` method. --- .../commands/node_file_structure_command.dart | 7 +++++++ .../commands/write_screen_command.dart | 13 +++++++------ .../commands/write_symbol_command.dart | 11 ++++++----- 3 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart new file mode 100644 index 00000000..60389f29 --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart @@ -0,0 +1,7 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; + +/// Class that relies on `code` to implement its `write` method. +abstract class NodeFileStructureCommand extends FileStructureCommand { + String code; + NodeFileStructureCommand(this.code); +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index fbf65817..13ee00d9 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -1,23 +1,24 @@ -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -class WriteScreenCommand implements FileStructureCommand { +class WriteScreenCommand implements NodeFileStructureCommand { + @override + String code; String name; String relativePath; - String data; final SCREEN_PATH = 'lib/modules'; - WriteScreenCommand(this.name, this.relativePath, this.data); + WriteScreenCommand(this.name, this.relativePath, this.code); - /// Writes a screen file containing [data] to [path] with [name] as its filename. + /// Writes a screen file containing [code] to [path] with [name] as its filename. /// /// Returns path to the file that was created. @override Future write(FileStructureStrategy strategy) { var absPath = '${strategy.GENERATED_PROJECT_PATH}$SCREEN_PATH/$relativePath/$name'; - strategy.pageWriter.write(data, absPath); + strategy.pageWriter.write(code, absPath); return Future.value(absPath); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 5f3196f8..3b76a3f2 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -1,12 +1,13 @@ -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -class WriteSymbolCommand implements FileStructureCommand { +class WriteSymbolCommand implements NodeFileStructureCommand { + @override + String code; String name; - String data; final String SYMBOL_PATH = 'lib/widgets'; - WriteSymbolCommand(this.name, this.data); + WriteSymbolCommand(this.name, this.code); /// Writes a symbol file containing [data] with [name] as its filename. /// @@ -14,7 +15,7 @@ class WriteSymbolCommand implements FileStructureCommand { @override Future write(FileStructureStrategy strategy) { var absPath = '${strategy.GENERATED_PROJECT_PATH}$SYMBOL_PATH/$name'; - strategy.pageWriter.write(data, absPath); + strategy.pageWriter.write(code, absPath); return Future.value(absPath); } } From fd1a6e583b64e439b18c40ad252342f6b45b2c3c Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 4 May 2021 19:21:46 -0600 Subject: [PATCH 035/404] Commands have ability to write and append files FileStructureCommands should be able to directly interact with `dart:io` to modify files. --- .../commands/add_constant_command.dart | 4 ++-- .../commands/add_dependency_command.dart | 5 ++-- .../commands/file_structure_command.dart | 24 +++++++++++++++++++ .../commands/write_screen_command.dart | 8 +++---- .../commands/write_symbol_command.dart | 8 +++---- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index b1f659bb..6ef1916e 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -1,7 +1,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -class AddConstantCommand implements FileStructureCommand { +class AddConstantCommand extends FileStructureCommand { String name; String type; String value; @@ -13,6 +13,6 @@ class AddConstantCommand implements FileStructureCommand { Future write(FileStructureStrategy strategy) { var constantStr = 'const $type $name = $value;'; var path = '${strategy.GENERATED_PROJECT_PATH}${CONST_PATH}'; - strategy.pageWriter.append(constantStr, path); + appendDataToFile(constantStr, path); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart index 108bcf56..7d106e03 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -1,7 +1,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -class AddDependencyCommand implements FileStructureCommand { +class AddDependencyCommand extends FileStructureCommand { String package; String version; @@ -9,6 +9,7 @@ class AddDependencyCommand implements FileStructureCommand { @override Future write(FileStructureStrategy strategy) { - strategy.pageWriter.addDependency(package, version); + // TODO: append the dependency to pubspec.yaml directly + throw UnimplementedError(); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart index f433e488..f3b493b8 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart @@ -1,5 +1,29 @@ +import 'dart:io'; + import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; abstract class FileStructureCommand { + /// Method that executes the [FileStructureCommand]'s action. Future write(FileStructureStrategy strategy); + + /// Writes `data` to file at `fileAbsPath`. + /// + /// [fileAbsPath] should be the absolute path of the file + void writeDataToFile(String data, String fileAbsPath) { + File(fileAbsPath).createSync(recursive: true); + var writer = File(fileAbsPath); + writer.writeAsStringSync(data); + } + + /// Appends [data] to the end of file located at [fileAbsPath]. + /// + /// Creates the file if the file at [fileAbsPath] does not exist. + void appendDataToFile(String data, String fileAbsPath) { + var file = File(fileAbsPath); + if (file.existsSync()) { + file.writeAsStringSync(data, mode: FileMode.append); + } else { + writeDataToFile(data, fileAbsPath); + } + } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 13ee00d9..e7a532ed 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -1,15 +1,13 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -class WriteScreenCommand implements NodeFileStructureCommand { - @override - String code; +class WriteScreenCommand extends NodeFileStructureCommand { String name; String relativePath; final SCREEN_PATH = 'lib/modules'; - WriteScreenCommand(this.name, this.relativePath, this.code); + WriteScreenCommand(this.name, this.relativePath, String code) : super(code); /// Writes a screen file containing [code] to [path] with [name] as its filename. /// @@ -18,7 +16,7 @@ class WriteScreenCommand implements NodeFileStructureCommand { Future write(FileStructureStrategy strategy) { var absPath = '${strategy.GENERATED_PROJECT_PATH}$SCREEN_PATH/$relativePath/$name'; - strategy.pageWriter.write(code, absPath); + writeDataToFile(code, absPath); return Future.value(absPath); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 3b76a3f2..e7497d00 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -1,13 +1,11 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -class WriteSymbolCommand implements NodeFileStructureCommand { - @override - String code; +class WriteSymbolCommand extends NodeFileStructureCommand { String name; final String SYMBOL_PATH = 'lib/widgets'; - WriteSymbolCommand(this.name, this.code); + WriteSymbolCommand(this.name, String code) : super(code); /// Writes a symbol file containing [data] with [name] as its filename. /// @@ -15,7 +13,7 @@ class WriteSymbolCommand implements NodeFileStructureCommand { @override Future write(FileStructureStrategy strategy) { var absPath = '${strategy.GENERATED_PROJECT_PATH}$SYMBOL_PATH/$name'; - strategy.pageWriter.write(code, absPath); + writeDataToFile(code, absPath); return Future.value(absPath); } } From 9f27f0438e8d73461676202f6e41d0d7c7843b9b Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 4 May 2021 19:47:07 -0600 Subject: [PATCH 036/404] Implement AddDependencyCommand write() This write() method appends a new dependency to pubspec.yaml. --- .../commands/add_constant_command.dart | 2 ++ .../commands/add_dependency_command.dart | 29 +++++++++++++++++-- .../commands/write_screen_command.dart | 1 + .../commands/write_symbol_command.dart | 1 + 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index 6ef1916e..c1b7e11a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +/// Command used to add a constant to the project's constants file class AddConstantCommand extends FileStructureCommand { String name; String type; @@ -9,6 +10,7 @@ class AddConstantCommand extends FileStructureCommand { AddConstantCommand(this.name, this.type, this.value); + /// Adds a constant containing `type`, `name` and `value` to `constants.dart` file @override Future write(FileStructureStrategy strategy) { var constantStr = 'const $type $name = $value;'; diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart index 7d106e03..ee600046 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -1,15 +1,38 @@ +import 'dart:io'; + import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +/// Command used to add a dependency to `pubspec.yaml` class AddDependencyCommand extends FileStructureCommand { String package; String version; AddDependencyCommand(this.package, this.version); + /// Appends `package` and `version` to `pubspec.yaml` dependencies. @override - Future write(FileStructureStrategy strategy) { - // TODO: append the dependency to pubspec.yaml directly - throw UnimplementedError(); + Future write(FileStructureStrategy strategy) async { + var yamlAbsPath = '${strategy.GENERATED_PROJECT_PATH}/pubspec.yaml'; + + var readYaml = File(yamlAbsPath).readAsLinesSync(); + + // Ensure dependency has not already been added + if (readYaml.contains('$package: $version')) { + return; + } + + var line = readYaml.indexOf('dependencies:'); + readYaml.insert(++line, '$package: $version'); + + // TODO: we may want to move this to a separate Command to ensure it only gets called once. + line = readYaml.indexOf('flutter:'); + if (line > 0) { + if (!readYaml.contains(' assets:')) { + readYaml.insert(++line, ' assets:\n - assets/images/'); + } + } + + writeDataToFile(readYaml.toString(), yamlAbsPath); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index e7a532ed..6023bfc0 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +/// Command that writes a `screen` to the project. class WriteScreenCommand extends NodeFileStructureCommand { String name; String relativePath; diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index e7497d00..e620639d 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +/// Command that writes a `symbol` to the project. class WriteSymbolCommand extends NodeFileStructureCommand { String name; final String SYMBOL_PATH = 'lib/widgets'; From bf992fa7c3d4b98ce0c7f2c9bee70a54e75499ef Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 5 May 2021 16:17:23 -0600 Subject: [PATCH 037/404] Move tree parity logic to Platform Linker Co-authored-by: Bryan Figueroa --- lib/controllers/interpret.dart | 2 -- .../helpers/pb_project.dart | 32 ------------------- .../services/pb_platform_linker_service.dart | 22 ++++++++++++- 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 261364ad..5f338590 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -65,8 +65,6 @@ class Interpret { } } - _pb_project.cleanTreeParity(); - return _pb_project; } diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index 3b00d445..045e1332 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -25,36 +25,4 @@ class PBProject { _genProjectData = PBGenerationProjectData(); _fileStructureStrategy = fileStructureStrategy; } - - // Pass through the forest once checking all trees - // if two or more trees have the same name and same - // orientation, a `_n` counter is added at the end - // of their name - void cleanTreeParity() { - forest.sort((a, b) => a.rootNode.name.compareTo(b.rootNode.name)); - var currentCounter = 0; - var nextCounter = currentCounter + 1; - var nameCounter = 1; - - while (nextCounter < forest.length) { - var currentTree = forest[currentCounter]; - var nextTree = forest[nextCounter]; - if (currentTree.rootNode.name.compareTo(nextTree.rootNode.name) == 0) { - if (currentTree.data.orientation == nextTree.data.orientation) { - forest[nextCounter].rootNode.name = - forest[nextCounter].rootNode.name + '_$nameCounter'; - - nameCounter++; - nextCounter++; - } else { - currentCounter = nextCounter; - nextCounter++; - } - } else { - currentCounter = nextCounter; - nextCounter++; - nameCounter = 1; - } - } - } } diff --git a/lib/interpret_and_optimize/services/pb_platform_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_linker_service.dart index 22cad2a0..da5a76f3 100644 --- a/lib/interpret_and_optimize/services/pb_platform_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_linker_service.dart @@ -13,6 +13,9 @@ class PBPlatformOrientationLinkerService { final Map> _map = {}; + /// Map that shows how many trees with the same name `key` exist. + final Map _mapCounter = {}; + /// Set of all platforms in the project final Set _platforms = {}; @@ -49,11 +52,28 @@ class PBPlatformOrientationLinkerService { /// Adds [tree] to the storage void addToMap(PBIntermediateTree tree) { - // TODO: check if we have exact trees (equal orientation and platform) if (_map.containsKey(tree.name)) { + // Check if we have exact trees (same orientation and platform) + var trees = _map[tree.name]; + for (var currTree in trees) { + var treeName = tree.rootNode.name; + var iterTreeName = currTree.rootNode.name; + if (treeName == iterTreeName && + tree.data.orientation == currTree.data.orientation && + tree.data.platform == currTree.data.platform) { + // Rename the tree if both trees have the same orientation and platform + tree.rootNode.name = treeName + '_${_mapCounter[tree.rootNode.name]}'; + _mapCounter[treeName]++; + } + } + _map[tree.name].add(tree); + if (!_mapCounter.containsKey(tree.rootNode.name)) { + _mapCounter[tree.rootNode.name] = 1; + } } else { _map[tree.name] = [tree]; + _mapCounter[tree.rootNode.name] = 1; } } From 81951fa1d5acfcc7c518ab16638d060d1ee7716a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 5 May 2021 16:18:57 -0600 Subject: [PATCH 038/404] Rename pb_platform_linker_service file --- ...r_service.dart => pb_platform_orientation_linker_service.dart} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/interpret_and_optimize/services/{pb_platform_linker_service.dart => pb_platform_orientation_linker_service.dart} (100%) diff --git a/lib/interpret_and_optimize/services/pb_platform_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart similarity index 100% rename from lib/interpret_and_optimize/services/pb_platform_linker_service.dart rename to lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart From a8e6c8e836e1383e1061bf9057f05cbd573df9a1 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 5 May 2021 16:27:07 -0600 Subject: [PATCH 039/404] Fix imports to platform orientation linker Co-authored-by: Bryan Figueroa --- lib/controllers/interpret.dart | 2 +- lib/generation/generators/util/pb_generation_view_data.dart | 2 +- .../responsive_layout_builder_template.dart | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 5f338590..d2e970d6 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -13,7 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_linker_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_visual_generation_service.dart'; diff --git a/lib/generation/generators/util/pb_generation_view_data.dart b/lib/generation/generators/util/pb_generation_view_data.dart index 2de965c1..02464c53 100644 --- a/lib/generation/generators/util/pb_generation_view_data.dart +++ b/lib/generation/generators/util/pb_generation_view_data.dart @@ -1,6 +1,6 @@ import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_linker_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; class PBGenerationViewData { final Map _globalVariables = {}; diff --git a/lib/generation/semi_constant_templates/responsive_layout_builder_template.dart b/lib/generation/semi_constant_templates/responsive_layout_builder_template.dart index 3d49e4e7..5c79abdf 100644 --- a/lib/generation/semi_constant_templates/responsive_layout_builder_template.dart +++ b/lib/generation/semi_constant_templates/responsive_layout_builder_template.dart @@ -2,7 +2,7 @@ import 'dart:collection'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/semi_constant_templates/semi_constant_template.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_linker_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; class ResponsiveLayoutBuilderTemplate implements SemiConstantTemplate { @override From b4aed83a0cb10c19ae4cc0e3d5829a1334f6ea46 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 6 May 2021 12:10:30 -0600 Subject: [PATCH 040/404] Create Observer pattern for FileStructureCommands Co-authored-by: Bryan Figueroa --- .../file_structure_strategy/command_invoker.dart | 5 +++++ .../pb_file_structure_strategy.dart | 9 ++++++++- .../pb_generation_configuration.dart | 4 ++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/command_invoker.dart diff --git a/lib/generation/generators/value_objects/file_structure_strategy/command_invoker.dart b/lib/generation/generators/value_objects/file_structure_strategy/command_invoker.dart new file mode 100644 index 00000000..041da391 --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/command_invoker.dart @@ -0,0 +1,5 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; + +abstract class CommandInvoker { + void commandCreated(FileStructureCommand command); +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index c09cbfb7..c43e5caf 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -1,4 +1,6 @@ import 'dart:io'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; @@ -11,7 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod /// ///For example, in the provider strategy, there would be a directory for the models and the providers, ///while something like BLoC will assign a directory to a single -abstract class FileStructureStrategy { +abstract class FileStructureStrategy implements CommandInvoker { ///The path of where all the views are going to be generated. /// ///The views is anything that is not a screen, for example, symbol masters @@ -97,4 +99,9 @@ abstract class FileStructureStrategy { String getViewPath(String fileName) => '${_viewDirectoryPath}${fileName}.dart'; + + @override + void commandCreated(FileStructureCommand command) { + command.write(this); + } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index aee4dadb..82b07c4a 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; @@ -53,6 +54,9 @@ abstract class GenerationConfiguration { final Map _dependencies = {}; Iterable> get dependencies => _dependencies.entries; + /// List of observers that will be notified when a new command is added. + final commandObservers = []; + ///This is going to modify the [PBIntermediateNode] in order to affect the structural patterns or file structure produced. Future applyMiddleware(PBIntermediateNode node) async { var it = _middleware.iterator; From 6deafaba4bf0bc2356e0feb03d6de3fa9b8ee938 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 6 May 2021 12:42:43 -0600 Subject: [PATCH 041/404] Initialize commandObservers when setting up config --- .../pb_generation_configuration.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 82b07c4a..c21ec0bb 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -42,11 +42,6 @@ abstract class GenerationConfiguration { set pageWriter(PBPageWriter pageWriter) => _pageWriter = pageWriter; - GenerationConfiguration() { - logger = Logger(runtimeType.toString()); - _generationManager = PBFlutterGenerator(data: PBGenerationViewData()); - } - PBGenerationManager get generationManager => _generationManager; set generationManager(PBGenerationManager manager) => _generationManager = manager; @@ -57,6 +52,11 @@ abstract class GenerationConfiguration { /// List of observers that will be notified when a new command is added. final commandObservers = []; + GenerationConfiguration() { + logger = Logger(runtimeType.toString()); + _generationManager = PBFlutterGenerator(data: PBGenerationViewData()); + } + ///This is going to modify the [PBIntermediateNode] in order to affect the structural patterns or file structure produced. Future applyMiddleware(PBIntermediateNode node) async { var it = _middleware.iterator; @@ -138,6 +138,7 @@ abstract class GenerationConfiguration { Future setUpConfiguration() async { fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, _pageWriter, pbProject); + commandObservers.add(fileStructureStrategy); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); } From c1457fb936d4f7950b586ac4a38a42fd43dcf231 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 6 May 2021 12:56:04 -0600 Subject: [PATCH 042/404] Add ResponsiveLayoutBuilderCommand This replaces the ResponsiveLayoutBuilderTemplate --- .../responsive_layout_builder_command.dart} | 17 +++++++++++++---- .../pb_platform_orientation_linker_service.dart | 4 +--- 2 files changed, 14 insertions(+), 7 deletions(-) rename lib/generation/{semi_constant_templates/responsive_layout_builder_template.dart => generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart} (78%) diff --git a/lib/generation/semi_constant_templates/responsive_layout_builder_template.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart similarity index 78% rename from lib/generation/semi_constant_templates/responsive_layout_builder_template.dart rename to lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 5c79abdf..717343d3 100644 --- a/lib/generation/semi_constant_templates/responsive_layout_builder_template.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -1,19 +1,26 @@ import 'dart:collection'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/generation/semi_constant_templates/semi_constant_template.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; -class ResponsiveLayoutBuilderTemplate implements SemiConstantTemplate { +class ResponsiveLayoutBuilderCommand extends FileStructureCommand { + final PATH_TO_RESPONSIVE_LAYOUT = + 'lib/widgets/responsive_layout_builder.dart'; + @override - String generateTemplate() { + Future write(FileStructureStrategy strategy) async { + var absPath = + '${strategy.GENERATED_PROJECT_PATH}$PATH_TO_RESPONSIVE_LAYOUT'; + var platforms = PBPlatformOrientationLinkerService() .platforms .map((platform) => platform.toString().split('.').last.toLowerCase()); var widgetVars = _generatePlatformWidgets(platforms); var widgetInit = _generatePlatformInitializers(platforms); var breakpointChecks = _generateBreakpointStatements(platforms); - return ''' + var template = ''' class ResponsiveLayoutBuilder extends StatelessWidget { ${widgetVars} @@ -36,6 +43,8 @@ class ResponsiveLayoutBuilderTemplate implements SemiConstantTemplate { } } '''; + + super.writeDataToFile(template, absPath); } String _generatePlatformWidgets(List platforms) { diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index da5a76f3..f782f206 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -1,4 +1,3 @@ -import 'package:parabeac_core/generation/semi_constant_templates/responsive_layout_builder_template.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:parabeac_core/generation/semi_constant_templates/orientation_builder_template.dart'; @@ -43,8 +42,7 @@ class PBPlatformOrientationLinkerService { // Add responsive layout builder template to the project // if there are more than 1 plataform on the project if (hasMultiplePlatforms()) { - tree.rootNode.currentContext.project.genProjectData - .addTemplate(ResponsiveLayoutBuilderTemplate()); + // TODO: call ResponsiveLayoutBuilderCommand } addToMap(tree); From 1b1e6044f3f90989ae0de0465d1d2f881c9ed0d3 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 6 May 2021 12:59:32 -0600 Subject: [PATCH 043/404] Add OrientationBuilderCommand This replaces the OrientationBuilderTemplate --- .../commands/orientation_builder_command.dart} | 16 ++++++++++++---- .../pb_platform_orientation_linker_service.dart | 6 ++---- 2 files changed, 14 insertions(+), 8 deletions(-) rename lib/generation/{semi_constant_templates/orientation_builder_template.dart => generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart} (63%) diff --git a/lib/generation/semi_constant_templates/orientation_builder_template.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart similarity index 63% rename from lib/generation/semi_constant_templates/orientation_builder_template.dart rename to lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart index c1e1d889..a601c9c7 100644 --- a/lib/generation/semi_constant_templates/orientation_builder_template.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart @@ -1,9 +1,15 @@ -import 'package:parabeac_core/generation/semi_constant_templates/semi_constant_template.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; + +class OrientationBuilderCommand extends FileStructureCommand { + final PATH_TO_ORIENTATION_BUILDER = + 'lib/widgets/responsive_orientation_builder.dart'; -class OrientationBuilderTemplate implements SemiConstantTemplate { @override - String generateTemplate() { - return ''' + Future write(FileStructureStrategy strategy) { + var fileAbsPath = + '${strategy.GENERATED_PROJECT_PATH}$PATH_TO_ORIENTATION_BUILDER'; + var template = ''' import 'package:flutter/material.dart'; class ResponsiveOrientationBuilder extends StatelessWidget { @@ -44,5 +50,7 @@ class OrientationBuilderTemplate implements SemiConstantTemplate { } '''; + + super.writeDataToFile(template, fileAbsPath); } } diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index f782f206..da3c9433 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -1,6 +1,5 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; -import 'package:parabeac_core/generation/semi_constant_templates/orientation_builder_template.dart'; class PBPlatformOrientationLinkerService { static final PBPlatformOrientationLinkerService _pbPlatformLinkerService = @@ -36,13 +35,12 @@ class PBPlatformOrientationLinkerService { // Add orientation builder template to the project // if there are more than 1 orientation on the project if (hasMultipleOrientations()) { - tree.rootNode.currentContext.project.genProjectData - .addTemplate(OrientationBuilderTemplate()); + // TODO: call OrientationBuilderCommand and notify observers } // Add responsive layout builder template to the project // if there are more than 1 plataform on the project if (hasMultiplePlatforms()) { - // TODO: call ResponsiveLayoutBuilderCommand + // TODO: call ResponsiveLayoutBuilderCommand and notify observers } addToMap(tree); From b119e2a606c251ef93346ba8c32a6d2a879f56c4 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 6 May 2021 13:00:29 -0600 Subject: [PATCH 044/404] Remove notion of SemiConstantTemplate This is because the Templates are effectively replaced with the FileStructureCommands. --- .../util/pb_generation_project_data.dart | 14 -------------- .../semi_constant_template.dart | 3 --- 2 files changed, 17 deletions(-) delete mode 100644 lib/generation/semi_constant_templates/semi_constant_template.dart diff --git a/lib/generation/generators/util/pb_generation_project_data.dart b/lib/generation/generators/util/pb_generation_project_data.dart index c20542e2..5700eb45 100644 --- a/lib/generation/generators/util/pb_generation_project_data.dart +++ b/lib/generation/generators/util/pb_generation_project_data.dart @@ -1,20 +1,6 @@ import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; -import 'package:parabeac_core/generation/semi_constant_templates/semi_constant_template.dart'; class PBGenerationProjectData { - // List of current templates on the project - List templates = []; - - // Add template to the project - // only if the template is not already part of - // current project's templates - void addTemplate(SemiConstantTemplate template) { - if (!templates - .any((element) => element.runtimeType == template.runtimeType)) { - templates.add(template); - } - } - void addDependencies(String packageName, String version) => PBFlutterWriter().addDependency(packageName, version); } diff --git a/lib/generation/semi_constant_templates/semi_constant_template.dart b/lib/generation/semi_constant_templates/semi_constant_template.dart deleted file mode 100644 index 981f79f2..00000000 --- a/lib/generation/semi_constant_templates/semi_constant_template.dart +++ /dev/null @@ -1,3 +0,0 @@ -abstract class SemiConstantTemplate { - String generateTemplate(); -} From b4d5734cdc2d11e9fd3fd05bf5382080cb936f0c Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 6 May 2021 15:01:32 -0600 Subject: [PATCH 045/404] Add screen tree type to scaffold trees --- lib/controllers/interpret.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 6a116419..65e6aa61 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -81,7 +81,9 @@ class Interpret { tempTree.data = PBGenerationViewData(); if (currentScreen.rootNode is InheritedScaffold) { - PBPlatformOrientationLinkerService().addOrientationPlatformInformation(tempTree); + tempTree.tree_type = TREE_TYPE.SCREEN; + PBPlatformOrientationLinkerService() + .addOrientationPlatformInformation(tempTree); } else if (currentScreen.rootNode is PBSharedMasterNode) { tempTree.tree_type = TREE_TYPE.VIEW; } else { From cfff09d5696278f883811e9886caf7593ae4a71d Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Fri, 7 May 2021 16:52:28 -0600 Subject: [PATCH 046/404] Added command queue and execution in PBGenConfig Co-Authored by bryan@parabeac.com --- .../util/pb_generation_project_data.dart | 4 +++ .../commands/export_platform_command.dart | 35 +++++++++++++++++++ .../pb_generation_configuration.dart | 7 ++++ ...b_platform_orientation_linker_service.dart | 8 +++-- 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart diff --git a/lib/generation/generators/util/pb_generation_project_data.dart b/lib/generation/generators/util/pb_generation_project_data.dart index 5700eb45..c8d90dc5 100644 --- a/lib/generation/generators/util/pb_generation_project_data.dart +++ b/lib/generation/generators/util/pb_generation_project_data.dart @@ -1,6 +1,10 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; class PBGenerationProjectData { void addDependencies(String packageName, String version) => PBFlutterWriter().addDependency(packageName, version); + + /// Queue where commands can be placed for later execution + final List commandQueue = []; } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart new file mode 100644 index 00000000..be664a1f --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -0,0 +1,35 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; + +/// Command to export `code` under a specific `platform` +class ExportPlatformCommand extends NodeFileStructureCommand { + PLATFORM platform; + String fileName; + String folderName; + + ExportPlatformCommand( + this.platform, + this.folderName, + this.fileName, + String code, + ) : super(code); + + @override + Future write(FileStructureStrategy strategy) async { + var path = '${strategy.GENERATED_PROJECT_PATH}'; + + switch (platform) { + case PLATFORM.DESKTOP: + path += 'lib/screens/$folderName/desktop/$fileName'; + break; + case PLATFORM.MOBILE: + path += 'lib/screens/$folderName/mobile/$fileName'; + break; + case PLATFORM.TABLET: + path += 'lib/screens/$folderName/tablet/$fileName'; + break; + } + super.writeDataToFile(code, path); + } +} diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index c21ec0bb..2b3d625e 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -139,6 +139,13 @@ abstract class GenerationConfiguration { fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, _pageWriter, pbProject); commandObservers.add(fileStructureStrategy); + + // Execute command queue + var queue = pbProject.genProjectData.commandQueue; + while (queue.isNotEmpty) { + var command = queue.removeLast(); + commandObservers.forEach((observer) => observer.commandCreated(command)); + } logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); } diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index da3c9433..2af9fb8a 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -1,3 +1,5 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -35,12 +37,14 @@ class PBPlatformOrientationLinkerService { // Add orientation builder template to the project // if there are more than 1 orientation on the project if (hasMultipleOrientations()) { - // TODO: call OrientationBuilderCommand and notify observers + tree.rootNode.currentContext.project.genProjectData.commandQueue + .add(OrientationBuilderCommand()); } // Add responsive layout builder template to the project // if there are more than 1 plataform on the project if (hasMultiplePlatforms()) { - // TODO: call ResponsiveLayoutBuilderCommand and notify observers + tree.rootNode.currentContext.project.genProjectData.commandQueue + .add(ResponsiveLayoutBuilderCommand()); } addToMap(tree); From a78f3e2f16372f3c11586c1a332dc0d2d87f9234 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 10 May 2021 14:47:32 -0600 Subject: [PATCH 047/404] Write breakpoints when having multiple platforms --- .../pb_platform_orientation_linker_service.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 2af9fb8a..ef6e81c1 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -1,3 +1,5 @@ +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -45,6 +47,7 @@ class PBPlatformOrientationLinkerService { if (hasMultiplePlatforms()) { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(ResponsiveLayoutBuilderCommand()); + _addBreakpoints(tree); } addToMap(tree); @@ -159,6 +162,17 @@ class PBPlatformOrientationLinkerService { return ORIENTATION.VERTICAL; } + + void _addBreakpoints(PBIntermediateTree tree) { + if (MainInfo().configurations.containsKey('breakpoints')) { + Map bp = MainInfo().configurations['breakpoints']; + bp.forEach((key, value) { + var cmd = AddConstantCommand(key, 'num', value.toString()); + tree.rootNode.currentContext.project.genProjectData.commandQueue + .add(cmd); + }); + } + } } enum PLATFORM { From f3372c52087df02a5f6ea27f0c091d90079b3c9e Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 10 May 2021 16:48:57 -0600 Subject: [PATCH 048/404] Add default breakpoints for configurations.json --- lib/configurations/configurations.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index 26ca0fa6..7722f196 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -5,5 +5,9 @@ "widgetSpacing": "Expanded", "layoutPrecedence": ["column", "row", "stack"] }, - "state-management": "none" + "state-management": "none", + "breakpoints": { + "tablet": 600, + "desktop": 1280 + } } From 6ae48bcef4119232798d3a2ca3a34fd68085ede9 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 10 May 2021 16:50:17 -0600 Subject: [PATCH 049/404] Fixed minor issues on responsive layout builder --- .../commands/responsive_layout_builder_command.dart | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 717343d3..ae757f6f 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -16,7 +16,8 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { var platforms = PBPlatformOrientationLinkerService() .platforms - .map((platform) => platform.toString().split('.').last.toLowerCase()); + .map((platform) => platform.toString().split('.').last.toLowerCase()) + .toList(); var widgetVars = _generatePlatformWidgets(platforms); var widgetInit = _generatePlatformInitializers(platforms); var breakpointChecks = _generateBreakpointStatements(platforms); @@ -65,11 +66,16 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { } // Get breakpoints from configurations and sort by value Map breakpoints = MainInfo().configurations['breakpoints']; + if (breakpoints == null) { + breakpoints = {}; + breakpoints['tablet'] = 600; + breakpoints['desktop'] = 1280; + } var sortedMap = SplayTreeMap.from( breakpoints, (a, b) => breakpoints[a].compareTo(breakpoints[b])); var result = ''; - for (var i; i < platforms.length; i++) { + for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; if (sortedMap.containsKey(platform)) { if (i == platforms.length - 1) { From c3dbf42964c25e85ff75a4346969fea0133e6da7 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 10 May 2021 17:47:41 -0600 Subject: [PATCH 050/404] Add default breakpoint for mobile --- lib/configurations/configurations.json | 7 ++++++- .../commands/responsive_layout_builder_command.dart | 7 ++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index 26ca0fa6..681348d0 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -5,5 +5,10 @@ "widgetSpacing": "Expanded", "layoutPrecedence": ["column", "row", "stack"] }, - "state-management": "none" + "state-management": "none", + "breakpoints": { + "mobile": 360, + "tablet": 600, + "desktop": 1280 + } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 717343d3..0801197f 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -16,7 +16,8 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { var platforms = PBPlatformOrientationLinkerService() .platforms - .map((platform) => platform.toString().split('.').last.toLowerCase()); + .map((platform) => platform.toString().split('.').last.toLowerCase()) + .toList(); var widgetVars = _generatePlatformWidgets(platforms); var widgetInit = _generatePlatformInitializers(platforms); var breakpointChecks = _generateBreakpointStatements(platforms); @@ -64,12 +65,12 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { return 'if(${platforms[0]} != null){return ${platforms[0]}Widget;}'; } // Get breakpoints from configurations and sort by value - Map breakpoints = MainInfo().configurations['breakpoints']; + var breakpoints = MainInfo().configurations['breakpoints']; var sortedMap = SplayTreeMap.from( breakpoints, (a, b) => breakpoints[a].compareTo(breakpoints[b])); var result = ''; - for (var i; i < platforms.length; i++) { + for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; if (sortedMap.containsKey(platform)) { if (i == platforms.length - 1) { From fc272c2e94c9ee388337aecda1e68de4932e7d49 Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Tue, 11 May 2021 11:46:22 -0600 Subject: [PATCH 051/404] Updated README (cherry picked from commit 96912055b79dc77d4ca3dffede06f71bdcf4fa58) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dee5ebc9..a7c534b5 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,8 @@ Our goal is to create a tool that passes a modern Turing Test: automatic code ge # Get Started -If you have any trouble with getting Parabeac-Core running, check out this video! [![Parabeac-Core Getting Started](https://img.youtube.com/vi/e4CJgPMNCyo/0.jpg)](https://www.youtube.com/watch?v=e4CJgPMNCyo&feature=youtu.be) +If you have any trouble with getting Parabeac-Core running you can watch our [macOS](https://www.youtube.com/watch?v=QGC1BAdjEc0&t=10s) or [Windows tutorial here](https://www.youtube.com/watch?v=Pr52-9Ni4Ds&t=2s)! +[![Parabeac-Core Getting Started macOS](https://i9.ytimg.com/vi/Pr52-9Ni4Ds/mq2.jpg?sqp=CPCC64QG&rs=AOn4CLA3y0VXCz729PZ-fXxnVNIR8pTVMQ)](https://www.youtube.com/watch?v=QGC1BAdjEc0&t=10s) Development on Windows [requires some extra setup](WINDOWS_SETUP.md). From 467814dc876790b0063ad4c0649490d11db60025 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 16:55:50 -0600 Subject: [PATCH 052/404] Added a platform tag to file name --- .../commands/export_platform_command.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index be664a1f..03f3d1c2 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -21,12 +21,15 @@ class ExportPlatformCommand extends NodeFileStructureCommand { switch (platform) { case PLATFORM.DESKTOP: + fileName = fileName.replaceAll('.dart', '_desktop.dart'); path += 'lib/screens/$folderName/desktop/$fileName'; break; case PLATFORM.MOBILE: + fileName = fileName.replaceAll('.dart', '_mobile.dart'); path += 'lib/screens/$folderName/mobile/$fileName'; break; case PLATFORM.TABLET: + fileName = fileName.replaceAll('.dart', '_tablet.dart'); path += 'lib/screens/$folderName/tablet/$fileName'; break; } From 471f6782fa7e3859b0f6c2b17009afd97beb8169 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 16:56:09 -0600 Subject: [PATCH 053/404] Added breakpoints defaults --- .../commands/responsive_layout_builder_command.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index ae757f6f..7a421275 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -65,9 +65,11 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { return 'if(${platforms[0]} != null){return ${platforms[0]}Widget;}'; } // Get breakpoints from configurations and sort by value - Map breakpoints = MainInfo().configurations['breakpoints']; + var breakpoints = MainInfo().configurations['breakpoints']; if (breakpoints == null) { + // TODO: Handle breakpoints being null breakpoints = {}; + breakpoints['mobile'] = 300; breakpoints['tablet'] = 600; breakpoints['desktop'] = 1280; } From f440d4d4aeb7bf6514000f9f239afef164bc4700 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 16:56:27 -0600 Subject: [PATCH 054/404] Changed modules for screens --- .../file_structure_strategy/commands/write_screen_command.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 6023bfc0..2ae20e0f 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -6,7 +6,7 @@ class WriteScreenCommand extends NodeFileStructureCommand { String name; String relativePath; - final SCREEN_PATH = 'lib/modules'; + final SCREEN_PATH = 'lib/screens'; WriteScreenCommand(this.name, this.relativePath, String code) : super(code); From a124ca929293a773924d91d47ad2f88ebf968a6b Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 16:56:54 -0600 Subject: [PATCH 055/404] Created a mixin for platfor and orientation generation --- ...platform_orientation_generation_mixin.dart | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart new file mode 100644 index 00000000..d2f5f084 --- /dev/null +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -0,0 +1,76 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; +import 'package:recase/recase.dart'; + +mixin PBPlatformOrientationGeneration { + void generatePlatformInstance(Map> platformsMap, + String screenName, PBProject mainTree) { + platformsMap.forEach((platform, screens) { + var formatedName = screenName.snakeCase.toLowerCase(); + if (screens.length > 1) { + _generateOrientationInstance(screenName, mainTree); + } + if (platformsMap.length > 1) { + mainTree.genProjectData.commandQueue.add(WriteScreenCommand( + formatedName + '_platform_builder.dart', + formatedName, + _getPlatformInstance(platformsMap, screenName), + )); + } + }); + } + + void _generateOrientationInstance(String screenName, PBProject mainTree) { + var formatedName = screenName.snakeCase.toLowerCase(); + mainTree.genProjectData.commandQueue.add(WriteScreenCommand( + formatedName + '_orientation_builder.dart', + formatedName, + _getOrientationInstance(screenName), + )); + } + + String _getPlatformInstance( + Map> platformsMap, String screenName) { + var className = screenName.pascalCase; + return ''' + import 'package:flutter/material.dart'; + import '../../widgets/responsive_layout_builder.dart'; + + class ${className}PlatformBuilder extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ResponsiveLayoutBuilder( + ${_getPlatformsWidgets(platformsMap, className)} + ); + } + } + '''; + } + + String _getPlatformsWidgets( + Map> platformsMap, String className) { + var result = ''; + platformsMap.forEach((platform, value) { + result += '${platform}Widget: ${className}_${platform}(),'; + }); + return result; + } + + String _getOrientationInstance(String screenName) { + var className = screenName.pascalCase; + return ''' + import 'package:flutter/material.dart'; + import '../../widgets/responsive_orientation_builder.dart'; + + class ${className}OrientationBuilder extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ResponsiveOrientationBuilder( + verticalPage: ${className}Vertical(), + horizontalPage: ${className}Horizontal(), + ); + } + } + '''; + } +} From 5e43032b814119ec4c298f81a9d41644a3dc6f77 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 16:57:49 -0600 Subject: [PATCH 056/404] Made a better getter for map --- ...b_platform_orientation_linker_service.dart | 59 +++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 2af9fb8a..86c31f27 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -52,9 +53,9 @@ class PBPlatformOrientationLinkerService { /// Adds [tree] to the storage void addToMap(PBIntermediateTree tree) { - if (_map.containsKey(tree.name)) { + if (_map.containsKey(tree.rootNode.name)) { // Check if we have exact trees (same orientation and platform) - var trees = _map[tree.name]; + var trees = _map[tree.rootNode.name]; for (var currTree in trees) { var treeName = tree.rootNode.name; var iterTreeName = currTree.rootNode.name; @@ -67,12 +68,12 @@ class PBPlatformOrientationLinkerService { } } - _map[tree.name].add(tree); + _map[tree.rootNode.name].add(tree); if (!_mapCounter.containsKey(tree.rootNode.name)) { _mapCounter[tree.rootNode.name] = 1; } } else { - _map[tree.name] = [tree]; + _map[tree.rootNode.name] = [tree]; _mapCounter[tree.rootNode.name] = 1; } } @@ -133,6 +134,56 @@ class PBPlatformOrientationLinkerService { /// Returns orientations of the project Set get orientations => _orientations; + Map>> getWhoNeedsAbstractInstance() { + var result = >>{}; + _map.forEach((key, value) { + if (value.length > 1) { + result[key] = _getPlatformAndOrientation(value); + } + }); + return result; + } + + Map> _getPlatformAndOrientation( + List list) { + var result = >{}; + list.forEach((value) { + var platform = _getPlatformString(value); + var orientation = _getOrientationString(value); + if (result.containsKey(platform)) { + result[platform].add(orientation); + } else { + result[platform] = []; + result[platform].add(orientation); + } + }); + return result; + } + + String _getOrientationString(PBIntermediateTree tree) { + switch (tree.data.orientation) { + case ORIENTATION.HORIZONTAL: + return 'horizontal'; + case ORIENTATION.VERTICAL: + return 'vertical'; + default: + return 'noOrientationDetected'; + } + } + + String _getPlatformString(PBIntermediateTree tree) { + switch (tree.data.platform) { + case PLATFORM.DESKTOP: + return 'desktop'; + case PLATFORM.MOBILE: + return 'mobile'; + case PLATFORM.TABLET: + return 'tablet'; + default: + return 'noPlatformDetected'; + } + } + /// Extracts and returns platform of the screen. /// /// Defaults to PLATFORM.MOBILE if no platform is given. From e3b99ba369ed6e6b0c74d802e36a84e4c97a5859 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 18:00:51 -0600 Subject: [PATCH 057/404] Removed changes --- .../commands/export_platform_command.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index 03f3d1c2..be664a1f 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -21,15 +21,12 @@ class ExportPlatformCommand extends NodeFileStructureCommand { switch (platform) { case PLATFORM.DESKTOP: - fileName = fileName.replaceAll('.dart', '_desktop.dart'); path += 'lib/screens/$folderName/desktop/$fileName'; break; case PLATFORM.MOBILE: - fileName = fileName.replaceAll('.dart', '_mobile.dart'); path += 'lib/screens/$folderName/mobile/$fileName'; break; case PLATFORM.TABLET: - fileName = fileName.replaceAll('.dart', '_tablet.dart'); path += 'lib/screens/$folderName/tablet/$fileName'; break; } From 91ba44e49ee0d860a7ee52bb1bc81a4bb4ba54c6 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 18:01:37 -0600 Subject: [PATCH 058/404] Extended mixin to get orientations and platforms to the file name --- ...platform_orientation_generation_mixin.dart | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index d2f5f084..a41cc81a 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -1,5 +1,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:recase/recase.dart'; mixin PBPlatformOrientationGeneration { @@ -73,4 +75,23 @@ mixin PBPlatformOrientationGeneration { } '''; } + + String getPlatformOrientationName(PBIntermediateNode node) { + var result = ''; + var map = PBPlatformOrientationLinkerService() + .getPlatformOrientationData(node.name); + + if (map.length > 1) { + var platform = PBPlatformOrientationLinkerService() + .getPlatformString(node.currentContext.treeRoot); + result += '_$platform'; + } + if (map[node.currentContext.treeRoot.data.platform].length > 1) { + var orientation = PBPlatformOrientationLinkerService() + .getOrientationString(node.currentContext.treeRoot); + result += '_$orientation'; + } + + return result; + } } From 5d1c3591b9ba414bda92e7fbf1b0d790e07633d5 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 18:01:55 -0600 Subject: [PATCH 059/404] Small corrections --- .../pb_platform_orientation_linker_service.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 86c31f27..6254257a 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -100,7 +100,7 @@ class PBPlatformOrientationLinkerService { /// } Map> getPlatformOrientationData(String name) { - var result = {}; + var result = >{}; if (_map.containsKey(name)) { var screens = _map[name]; @@ -148,8 +148,8 @@ class PBPlatformOrientationLinkerService { List list) { var result = >{}; list.forEach((value) { - var platform = _getPlatformString(value); - var orientation = _getOrientationString(value); + var platform = getPlatformString(value); + var orientation = getOrientationString(value); if (result.containsKey(platform)) { result[platform].add(orientation); } else { @@ -160,7 +160,7 @@ class PBPlatformOrientationLinkerService { return result; } - String _getOrientationString(PBIntermediateTree tree) { + String getOrientationString(PBIntermediateTree tree) { switch (tree.data.orientation) { case ORIENTATION.HORIZONTAL: return 'horizontal'; @@ -171,7 +171,7 @@ class PBPlatformOrientationLinkerService { } } - String _getPlatformString(PBIntermediateTree tree) { + String getPlatformString(PBIntermediateTree tree) { switch (tree.data.platform) { case PLATFORM.DESKTOP: return 'desktop'; From b564b4fb44b8880a55c3830c271d0d7b02ede14f Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 18:02:14 -0600 Subject: [PATCH 060/404] Generate plataform and orientation abstract isntances --- .../flutter_project_builder/flutter_project_builder.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index ce766e37..11aa081d 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -127,6 +127,8 @@ class FlutterProjectBuilder { } } await Future.wait(PBStateManagementLinker().stateQueue, eagerError: true); + await generationConfiguration + .generatePlataformAndOrientationInstance(mainTree); await generationConfiguration.generateProject(mainTree); var l = File('${pathToFlutterProject}lib/main.dart').readAsLinesSync(); From 36ca8be8d85cdd3542fd1f6657c074179e40cc2a Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 11 May 2021 18:03:15 -0600 Subject: [PATCH 061/404] Added mixin and used commands instead of generation manager --- .../pb_generation_configuration.dart | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 2b3d625e..8bccb8a5 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -2,6 +2,9 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.d import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; @@ -17,10 +20,11 @@ import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; -abstract class GenerationConfiguration { +abstract class GenerationConfiguration with PBPlatformOrientationGeneration { FileStructureStrategy fileStructureStrategy; Logger logger; @@ -184,9 +188,37 @@ abstract class GenerationConfiguration { /// we can ignore them here /// TODO: change it } else { - await pbProject.fileStructureStrategy.generatePage( - await _generationManager.generate(node), filename, - args: node is InheritedScaffold ? 'SCREEN' : 'VIEW'); + var fileName = node?.name?.snakeCase ?? 'no_name_found'; + if (node.currentContext.treeRoot.data.platform == null) { + // TODO: remove commented code + //if WriteSymbolCommand works, needs extensive testing + // await pbProject.fileStructureStrategy.generatePage( + // await _generationManager.generate(node), filename, + // args: node is InheritedScaffold ? 'SCREEN' : 'VIEW'); + + node.currentContext.project.genProjectData.commandQueue + .add(WriteSymbolCommand( + '$fileName.dart', + _generationManager.generate(node), + )); + } else { + var completeFileName = fileName + getPlatformOrientationName(node); + node.currentContext.project.genProjectData.commandQueue + .add(ExportPlatformCommand( + node.currentContext.treeRoot.data.platform, + fileName, + '$completeFileName.dart', + await _generationManager.generate(node), + )); + } } } + + Future generatePlataformAndOrientationInstance(PBProject mainTree) { + var currentMap = + PBPlatformOrientationLinkerService().getWhoNeedsAbstractInstance(); + currentMap.forEach((screenName, platformsMap) { + generatePlatformInstance(platformsMap, screenName, mainTree); + }); + } } From fbd6191b01bed5ca79d718fadad2276477bc830f Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 12 May 2021 11:47:24 -0600 Subject: [PATCH 062/404] Export files to respective platform --- .../pb_generation_configuration.dart | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 2b3d625e..c6996787 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -17,6 +17,7 @@ import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; @@ -107,6 +108,7 @@ abstract class GenerationConfiguration { ///generates the Project based on the [pb_project] Future generateProject(PBProject pb_project) async { pbProject = pb_project; + var poLinker = PBPlatformOrientationLinkerService(); await setUpConfiguration(); pbProject.fileStructureStrategy = fileStructureStrategy; @@ -123,7 +125,17 @@ abstract class GenerationConfiguration { _commitImports(tree.rootNode, tree.name.snakeCase, fileName); - await _generateNode(tree.rootNode, '${tree.name.snakeCase}/${fileName}'); + if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { + var platformFolder = tree.rootNode.managerData.platform + .toString() + .toLowerCase() + .replaceFirst('platform.', ''); + await _generateNode( + tree.rootNode, '${fileName}/$platformFolder/$fileName'); + } else { + await _generateNode( + tree.rootNode, '${tree.name.snakeCase}/${fileName}'); + } } await _commitDependencies(pb_project.projectName); } From 4d8bdfe03ec28e4cc4e04626f1de33e3e03e1cae Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 12 May 2021 11:48:26 -0600 Subject: [PATCH 063/404] Add helper method to retrieve platform string Add helper method to check whether a tree has multiple platforms/orientations. --- ...b_platform_orientation_linker_service.dart | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 2af9fb8a..85af0790 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -52,11 +52,12 @@ class PBPlatformOrientationLinkerService { /// Adds [tree] to the storage void addToMap(PBIntermediateTree tree) { - if (_map.containsKey(tree.name)) { + var key = tree.rootNode.name; + if (_map.containsKey(key)) { // Check if we have exact trees (same orientation and platform) - var trees = _map[tree.name]; + var trees = _map[key]; for (var currTree in trees) { - var treeName = tree.rootNode.name; + var treeName = key; var iterTreeName = currTree.rootNode.name; if (treeName == iterTreeName && tree.data.orientation == currTree.data.orientation && @@ -67,13 +68,13 @@ class PBPlatformOrientationLinkerService { } } - _map[tree.name].add(tree); - if (!_mapCounter.containsKey(tree.rootNode.name)) { - _mapCounter[tree.rootNode.name] = 1; + _map[key].add(tree); + if (!_mapCounter.containsKey(key)) { + _mapCounter[key] = 1; } } else { - _map[tree.name] = [tree]; - _mapCounter[tree.rootNode.name] = 1; + _map[key] = [tree]; + _mapCounter[key] = 1; } } @@ -133,6 +134,15 @@ class PBPlatformOrientationLinkerService { /// Returns orientations of the project Set get orientations => _orientations; + /// Returns `true` if screen with `name` has more than one platform. + /// Returns `false` otherwise. + bool screenHasMultiplePlatforms(String name) => + _map.containsKey(name) && _map[name].length > 1; + + /// Removes the `PLATFORM.` prefix from platform and returns the stripped platform. + String stripPlatform(PLATFORM platform) => + platform.toString().toLowerCase().replaceFirst('platform.', ''); + /// Extracts and returns platform of the screen. /// /// Defaults to PLATFORM.MOBILE if no platform is given. From 016ecad08344d13c5f6abc5abbf3791d0ff85e12 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 12 May 2021 11:49:02 -0600 Subject: [PATCH 064/404] Add imports uses linker to adjust import info. --- .../file_structure_strategy/pb_file_structure_strategy.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index c43e5caf..34b7341b 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; @@ -68,6 +69,7 @@ abstract class FileStructureStrategy implements CommandInvoker { ///Add the import information to correctly generate them in the corresponding files. void addImportsInfo(PBIntermediateTree tree) { + var poLinker = PBPlatformOrientationLinkerService(); // Add to cache if node is scaffold or symbol master var node = tree.rootNode; var name = node?.name?.snakeCase; @@ -76,6 +78,10 @@ abstract class FileStructureStrategy implements CommandInvoker { var path = node is PBSharedMasterNode ? '${_viewDirectoryPath}${tree.name.snakeCase}/${name}.dart' // Removed .g : '${_screenDirectoryPath}${tree.name.snakeCase}/${name}.dart'; + if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { + path = + '${_screenDirectoryPath}$name/${poLinker.stripPlatform(tree.rootNode.managerData.platform)}/$name.dart'; + } PBGenCache().setPathToCache(uuid, path); } else { logger.warning( From 34d9f24dfb0490690a74d3744f1617a492c73416 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 12 May 2021 11:50:10 -0600 Subject: [PATCH 065/404] PBGenConfig uses platformLinker's platform strip method. --- .../pb_generation_configuration.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index c6996787..89124996 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -126,10 +126,8 @@ abstract class GenerationConfiguration { _commitImports(tree.rootNode, tree.name.snakeCase, fileName); if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { - var platformFolder = tree.rootNode.managerData.platform - .toString() - .toLowerCase() - .replaceFirst('platform.', ''); + var platformFolder = + poLinker.stripPlatform(tree.rootNode.managerData.platform); await _generateNode( tree.rootNode, '${fileName}/$platformFolder/$fileName'); } else { From 569f7a7f4372cfeee124544298da6f941fe2286b Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 12 May 2021 11:52:30 -0600 Subject: [PATCH 066/404] Add import to material in ResponsiveLayoutBuilder --- .../commands/responsive_layout_builder_command.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 0801197f..6089f711 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -21,7 +21,9 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { var widgetVars = _generatePlatformWidgets(platforms); var widgetInit = _generatePlatformInitializers(platforms); var breakpointChecks = _generateBreakpointStatements(platforms); + //TODO: use imports system to import material. See updated orientation builder command var template = ''' + import 'package:flutter/material.dart'; class ResponsiveLayoutBuilder extends StatelessWidget { ${widgetVars} From 6e0e24f3e5904d03a7fe9da578cff527918985cf Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 12 May 2021 12:02:03 -0600 Subject: [PATCH 067/404] Fix not importing screens on main.dart --- .../pb_generation_configuration.dart | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 89124996..d1d844e7 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -116,23 +116,27 @@ abstract class GenerationConfiguration { tree.data.addImport('package:flutter/material.dart'); _generationManager.data = tree.data; var fileName = tree.rootNode?.name?.snakeCase ?? 'no_name_found'; + + // Relative path to the file to create + var relPath = '${tree.name.snakeCase}/$fileName'; + // Change relative path if current tree is part of multi-platform setup + if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { + var platformFolder = + poLinker.stripPlatform(tree.rootNode.managerData.platform); + relPath = '${fileName}/$platformFolder/$fileName'; + } if (tree.rootNode is InheritedScaffold && (tree.rootNode as InheritedScaffold).isHomeScreen) { - await _setMainScreen( - tree.rootNode, '${tree.name.snakeCase}/${fileName}.dart'); + await _setMainScreen(tree.rootNode, '$relPath.dart'); } await _iterateNode(tree.rootNode); _commitImports(tree.rootNode, tree.name.snakeCase, fileName); if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { - var platformFolder = - poLinker.stripPlatform(tree.rootNode.managerData.platform); - await _generateNode( - tree.rootNode, '${fileName}/$platformFolder/$fileName'); + await _generateNode(tree.rootNode, '$relPath'); } else { - await _generateNode( - tree.rootNode, '${tree.name.snakeCase}/${fileName}'); + await _generateNode(tree.rootNode, '$relPath'); } } await _commitDependencies(pb_project.projectName); From b337aed210543b1cd5ef92b7f9897a8c5350a20b Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Wed, 12 May 2021 22:47:08 -0600 Subject: [PATCH 068/404] WIP added the iterator that would allow the traverse the trees in a topological manner. Additionally, added the ability for a node within the scope of the tree's context to add a dependent. --- lib/controllers/interpret.dart | 2 +- .../import_helper.dart | 74 +++++++++++++++++++ .../state_management/bloc_middleware.dart | 2 +- .../state_management/provider_middleware.dart | 2 +- .../state_management/riverpod_middleware.dart | 2 +- .../state_management/stateful_middleware.dart | 2 +- .../utils/middleware_utils.dart | 4 +- .../symbols/pb_instancesym_gen.dart | 2 +- .../entities/pb_shared_master_node.dart | 10 +-- .../subclasses/pb_intermediate_node.dart | 2 +- .../helpers/pb_context.dart | 18 ++--- .../helpers/pb_intermediate_node_tree.dart | 5 +- .../pb_shared_aggregation_service.dart | 6 +- test/lib/generation/import_test.dart | 30 +++++++- .../services/symbol_link_test.dart | 45 +++++------ test/lib/layouts/layout_generation_test.dart | 29 ++------ test/lib/middleware/bloc_test.dart | 2 +- test/lib/middleware/provider_test.dart | 2 +- test/lib/middleware/stateful_test.dart | 2 +- 19 files changed, 160 insertions(+), 81 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 8c0f60ed..89dd0499 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -107,7 +107,7 @@ class Interpret { /// VisualGenerationService var intermediateTree = PBIntermediateTree(designScreen.designNode.name); - currentContext.treeRoot = intermediateTree; + currentContext.tree = intermediateTree; currentContext.project = _pb_project; intermediateTree.rootNode = await visualGenerationService( parentComponent, currentContext, stopwatch); diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 12b529f0..b83ed90a 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -1,3 +1,5 @@ +import 'dart:collection'; + import 'package:parabeac_core/eggs/injected_app_bar.dart'; import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; @@ -57,3 +59,75 @@ class ImportHelper { return imports; } } + +///Iterating through the screens in a manner where, the screens that are +///dependent are processed first. +class IntermediateTopoIterator + implements Iterator { + List nodes; + + E _currentElement; + + @override + E get current => _currentElement; + + IntermediateTopoIterator(this.nodes) { + nodes = topologicalSort(nodes); + if (nodes.isNotEmpty) { + _currentElement = nodes.removeAt(0); + } + } + + HashMap _inDegrees(List screens) { + var inDegree = HashMap(); + screens.forEach((screen) { + inDegree.putIfAbsent(screen, () => 0); + screen.dependentOn.forEach((dependent) { + inDegree.update(dependent, (value) => value + 1, ifAbsent: () => 1); + }); + }); + return inDegree; + } + + ///Performing topological sort in the on the screens that were received. + List topologicalSort(List items) { + var ordered = []; + var noInDegrees = {}; + var inDegrees = _inDegrees(items); + + inDegrees.forEach((key, value) { + if (value == 0) { + noInDegrees.add(key); + } + }); + + while (noInDegrees.isNotEmpty) { + var vertex = noInDegrees.first; + noInDegrees.remove(vertex); + ordered.add(vertex); + + vertex.dependentOn.forEach((dependent) { + inDegrees[dependent] = inDegrees[dependent] - 1; + if (inDegrees[dependent] == 0) { + noInDegrees.add(dependent); + } + }); + } + + if (_detectCycle(inDegrees)) {} + return ordered; + } + + bool _detectCycle(HashMap inDegrees) { + return inDegrees.values.where((element) => element > 0).isNotEmpty; + } + + @override + bool moveNext() { + if (screens.isNotEmpty && _currentElement != null) { + _currentElement = screens.removeAt(0); + return true; + } + return false; + } +} diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index ba428645..788b16ec 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -60,7 +60,7 @@ class BLoCMiddleware extends Middleware { var isFirst = true; await states.forEach((element) { - element.currentContext.treeRoot.data = node.managerData; + element.currentContext.tree.data = node.managerData; element.generator.templateStrategy = BLoCStateTemplateStrategy( isFirst: isFirst, abstractClassName: parentState, diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 6151a5bf..2f05c50b 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -35,7 +35,7 @@ class ProviderMiddleware extends Middleware { var widgetName = node.functionCallName.camelCase; var watcher; - if (node.currentContext.treeRoot.rootNode.generator.templateStrategy + if (node.currentContext.tree.rootNode.generator.templateStrategy is StatelessTemplateStrategy) { watcher = PBVariable(watcherName, 'final ', true, '${getName(node.functionCallName).pascalCase}().${widgetName}'); diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index b3279294..319d3373 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -32,7 +32,7 @@ class RiverpodMiddleware extends Middleware { var watcher = PBVariable(watcherName + '_provider', 'final ', true, 'ChangeNotifierProvider((ref) => ${getName(node.functionCallName).pascalCase}())'); - if (node.currentContext.treeRoot.rootNode.generator.templateStrategy + if (node.currentContext.tree.rootNode.generator.templateStrategy is StatelessTemplateStrategy) { managerData.addGlobalVariable(watcher); } else { diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 492f69f9..b4d8d1cc 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -27,7 +27,7 @@ class StatefulMiddleware extends Middleware { }); await states.forEach((element) async { - element.currentContext.treeRoot.data = node.managerData; + element.currentContext.tree.data = node.managerData; await fileStrategy.generatePage( await generationManager.generate(element), '${parentDirectory}/${element.name.snakeCase}', diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 8271edac..767e49c2 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -28,7 +28,7 @@ class MiddlewareUtils { stateBuffer.write(MiddlewareUtils.generateVariable(node)); } node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - state.variation.node.currentContext.treeRoot.data = node.managerData; + state.variation.node.currentContext.tree.data = node.managerData; var variationNode = state.variation.node; if (variationNode is PBSharedMasterNode && @@ -69,7 +69,7 @@ class MiddlewareUtils { ) { // Pass down manager data to states node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - state.variation.node.currentContext.treeRoot.data = node.managerData; + state.variation.node.currentContext.tree.data = node.managerData; }); return ''' ${manager.generateImports()} diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 7d30d577..0113a7ae 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -62,7 +62,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { break; case TextStyle: // hack to include import - source.currentContext.treeRoot.data.addImport( + source.currentContext.tree.data.addImport( 'package:${MainInfo().projectName}/document/shared_props.g.dart'); buffer.write( '${param.name}: ${SharedStyle_UUIDToName[param.value] ?? "TextStyle()"},'); diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 8cc1e2e0..e66cd46f 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -14,7 +14,6 @@ import 'package:quick_log/quick_log.dart'; class PBSharedMasterNode extends PBVisualIntermediateNode implements PBInheritedIntermediate { - ///SERVICE var log = Logger('PBSharedMasterNode'); @@ -57,7 +56,6 @@ class PBSharedMasterNode extends PBVisualIntermediateNode PBContext currentContext, }) : super(topLeftCorner, bottomRightCorner, currentContext, name, UUID: originalRef.UUID ?? '') { - try { //Remove any special characters and leading numbers from the method name friendlyName = name @@ -68,9 +66,9 @@ class PBSharedMasterNode extends PBVisualIntermediateNode friendlyName = friendlyName[0].toUpperCase() + friendlyName.substring(1); } catch (e, stackTrace) { MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); + exception: e, + stackTrace: stackTrace, + ); log.error(e.toString()); } ; @@ -94,7 +92,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode p.canOverride, p.propertyName, /* Removed Parameter Defintion as it was accepting JSON?*/ - null, // TODO: @Eddie + null, currentContext.screenTopLeftCorner.x, currentContext.screenTopLeftCorner.y, currentContext.screenBottomRightCorner.x, diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 50506eda..455a8216 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -50,7 +50,7 @@ abstract class PBIntermediateNode { PBContext currentContext; - PBGenerationViewData get managerData => currentContext.treeRoot.data; + PBGenerationViewData get managerData => currentContext.tree.data; Map size; diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 4fc1fd08..4cd5bab7 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -1,4 +1,3 @@ -import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -6,21 +5,16 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class PBContext { - PBConfiguration configuration; + final PBConfiguration configuration; Point screenTopLeftCorner, screenBottomRightCorner; - Map jsonConfigurations; - PBIntermediateTree treeRoot; + PBIntermediateTree tree; PBProject project; - PBGenerationViewData get managerData => treeRoot?.data; + PBGenerationViewData get managerData => tree?.data; - PBContext({this.jsonConfigurations}) { - assert(jsonConfigurations != null); - var copyConfig = {}..addAll(jsonConfigurations); - copyConfig.remove('default'); + PBContext(this.configuration, {this.tree}); - configuration = PBConfiguration( - jsonConfigurations[MainInfo().configurationType], jsonConfigurations); - configuration.configurations = jsonConfigurations; + void addDependent(PBIntermediateTree dependet) { + tree.dependentsOn.add(dependet); } } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 4079f099..d0452fda 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -10,7 +10,10 @@ enum TREE_TYPE { class PBIntermediateTree { PBGenerationViewData data; PBIntermediateNode rootNode; + List dependentsOn; String name; - PBIntermediateTree(this.name); + PBIntermediateTree(this.name) { + dependentsOn = []; + } TREE_TYPE tree_type = TREE_TYPE.SCREEN; } diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index a69cf8d2..b649a246 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -54,7 +54,8 @@ class PBSharedInterAggregationService { // add Designer Warning here, not even sure if this is the designers fault or not log.warning('UUID: ${targetUUID} not found in searchNodeByUUID'); } - if ((prop.value != null) && (prop.type == PBSharedInstanceIntermediateNode)) { + if ((prop.value != null) && + (prop.type == PBSharedInstanceIntermediateNode)) { ///if the [PBSharedMasterNode] contains [PBSharedInstanceIntermediateNode] as parameters ///then its going gather the information of its [PBSharedMasterNode]. gatherSharedValues(prop.value); @@ -102,6 +103,9 @@ class PBSharedInterAggregationService { }).toList() ..removeWhere((v) => v == null || v.value == null); + instanceIntermediateNode.currentContext + .addDependent(masterNode.currentContext.tree); + ///Get the attributes of the [masterNode] to the [instanceIntermediateNode] here ([instanceIntermediateNode] attributes) instanceIntermediateNode.functionCallName = masterNode.name; instanceIntermediateNode.foundMaster = true; diff --git a/test/lib/generation/import_test.dart b/test/lib/generation/import_test.dart index 87818ac3..761a46b8 100644 --- a/test/lib/generation/import_test.dart +++ b/test/lib/generation/import_test.dart @@ -1,6 +1,7 @@ import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:test/test.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -34,13 +35,40 @@ void main() { when(importee2.child).thenReturn(importee3); }); + test('Testing how [PBIntermediateTree] are processed.', () { + ///[PBIntermediateTree]s that are going to be generated. The treees inside of the list + ///are dependent on each other, therefore, to ensure import availability, trees need to + ///be written in a certain manner. + var pbIntermeidateTrees = []; + + /// `tree1` is going to depend on `tree0` and `tree0` depends on `tree2`. + /// t0 + /// / \ + /// t1 t2 + var tree0 = PBIntermediateTree('Tree0'); + var tree1 = PBIntermediateTree('Tree1'); + var tree2 = PBIntermediateTree('Tree2'); + + tree1.dependentsOn.add(tree0); + tree0.dependentsOn.add(tree2); + pbIntermeidateTrees.addAll([tree0, tree2, tree1]); + + var dependencyIterator = + IntermediateTopoIterator(pbIntermeidateTrees); + var correctOrder = [tree1, tree0, tree2].iterator; + while (dependencyIterator.moveNext() && correctOrder.moveNext()) { + expect(dependencyIterator.current == correctOrder.current, true); + } + }); + test('Testing import generation when imports are generated', () { //Add symbol in the same folder as importer genCache.setPathToCache(importee1.UUID, '/path/to/page/importee1.dart'); //Add symbol located a directory above importer genCache.setPathToCache(importee2.UUID, '/path/to/importee2.dart'); //Add symbol located a directory below importer - genCache.setPathToCache(importee3.UUID, '/path/to/page/sub/importee3.dart'); + genCache.setPathToCache( + importee3.UUID, '/path/to/page/sub/importee3.dart'); // Find the imports of importer.dart var imports = ImportHelper.findImports( diff --git a/test/lib/interpret_and_optimize/services/symbol_link_test.dart b/test/lib/interpret_and_optimize/services/symbol_link_test.dart index 060a409c..60f46b21 100644 --- a/test/lib/interpret_and_optimize/services/symbol_link_test.dart +++ b/test/lib/interpret_and_optimize/services/symbol_link_test.dart @@ -4,7 +4,9 @@ import 'package:parabeac_core/input/sketch/entities/layers/symbol_master.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:test/test.dart'; @@ -41,6 +43,13 @@ void main() { width: 200, height: 200, )); + var configurations = PBConfiguration.fromJson({ + 'widgetStyle': 'Material', + 'widgetType': 'Stateless', + 'widgetSpacing': 'Expanded', + 'layoutPrecedence': ['column', 'row', 'stack'], + 'state-management': 'none' + }); masterNode = PBSharedMasterNode( mockReference, @@ -49,35 +58,17 @@ void main() { Point(0, 0), Point(0, 0), overridableProperties: [], - currentContext: PBContext(jsonConfigurations: { - "default": { - "widgetStyle": "Material", - "widgetType": "Stateless", - "widgetSpacing": "Expanded", - "layoutPrecedence": ["column", "row", "stack"] - }, - "stack": { - "widgetStyle": "Material", - "widgetType": "Stateless", - "widgetSpacing": "Expanded", - "layoutPrecedence": ["stack"] - }, - "This will be replaced by a Object ID to determine specific configurations for each page": - { - "widgetStyle": "Material", - "widgetType": "Stateless", - "widgetSpacing": "Expanded" - }, - "root": "AC2E7423-4609-4F37-8BCA-7E915944FFE2" - }), - ); - instanceNode = PBSharedInstanceIntermediateNode( - secondReference, - '02353', - sharedParamValues: [], + currentContext: PBContext(configurations, + tree: PBIntermediateTree('Symbol Master')), ); + instanceNode = PBSharedInstanceIntermediateNode(secondReference, '02353', + sharedParamValues: [], + currentContext: PBContext(configurations, + tree: PBIntermediateTree('SymbolInstance'))); }); - test('', () async { + test( + 'Testing the linking of [PBSharedMasterNode] and [PBSharedInstanceIntermediateNode]', + () async { await pbSymbolLinkerService.linkSymbols(masterNode); PBSharedInstanceIntermediateNode result = await pbSymbolLinkerService.linkSymbols(instanceNode); diff --git a/test/lib/layouts/layout_generation_test.dart b/test/lib/layouts/layout_generation_test.dart index 8ee3f755..9fadd7f9 100644 --- a/test/lib/layouts/layout_generation_test.dart +++ b/test/lib/layouts/layout_generation_test.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -22,27 +23,13 @@ void main() { TempGroupMock tempGroup; MainInfo().configurationType = 'default'; - PBContext currentContext = PBContext(jsonConfigurations: { - "default": { - "widgetStyle": "Material", - "widgetType": "Stateless", - "widgetSpacing": "Expanded", - "layoutPrecedence": ["column", "row", "stack"] - }, - "stack": { - "widgetStyle": "Material", - "widgetType": "Stateless", - "widgetSpacing": "Expanded", - "layoutPrecedence": ["stack"] - }, - "This will be replaced by a Object ID to determine specific configurations for each page": - { - "widgetStyle": "Material", - "widgetType": "Stateless", - "widgetSpacing": "Expanded" - }, - "root": "AC2E7423-4609-4F37-8BCA-7E915944FFE2" - }); + var currentContext = PBContext(PBConfiguration.fromJson({ + 'widgetStyle': 'Material', + 'widgetType': 'Stateless', + 'widgetSpacing': 'Expanded', + 'layoutPrecedence': ['column', 'row', 'stack'], + 'state-management': 'none' + })); setUp(() { leftItem = PBIntermediateNodeMock(); diff --git a/test/lib/middleware/bloc_test.dart b/test/lib/middleware/bloc_test.dart index 241f22da..b668684d 100644 --- a/test/lib/middleware/bloc_test.dart +++ b/test/lib/middleware/bloc_test.dart @@ -83,7 +83,7 @@ void main() { /// Context when(mockContext.project).thenReturn(mockProject); - when(mockContext.treeRoot).thenReturn(mockTree); + when(mockContext.tree).thenReturn(mockTree); /// Project when(mockProject.genProjectData).thenReturn(mockPBGenerationProjectData); diff --git a/test/lib/middleware/provider_test.dart b/test/lib/middleware/provider_test.dart index 5a8552fd..673e6723 100644 --- a/test/lib/middleware/provider_test.dart +++ b/test/lib/middleware/provider_test.dart @@ -98,7 +98,7 @@ void main() { /// Context when(mockContext.project).thenReturn(mockProject); - when(mockContext.treeRoot).thenReturn(mockTree); + when(mockContext.tree).thenReturn(mockTree); /// Project when(mockProject.genProjectData).thenReturn(mockPBGenerationProjectData); diff --git a/test/lib/middleware/stateful_test.dart b/test/lib/middleware/stateful_test.dart index f4fb3ab0..0c3e35e4 100644 --- a/test/lib/middleware/stateful_test.dart +++ b/test/lib/middleware/stateful_test.dart @@ -83,7 +83,7 @@ void main() { /// Context when(mockContext.project).thenReturn(mockProject); - when(mockContext.treeRoot).thenReturn(mockTree); + when(mockContext.tree).thenReturn(mockTree); /// Project when(mockProject.genProjectData).thenReturn(mockPBGenerationProjectData); From 08c475ab8890113154ee38ea5d684b469d7ee1ed Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Wed, 12 May 2021 22:48:35 -0600 Subject: [PATCH 069/404] WIP refactored the configurations to serialize the JSON file into the dart file directly instead of doing the mapping manually(less prone to bugs and human errors). Modified the structure of the configuration, there was no need for the flag 'default', therefore, that flag has been removed. --- lib/controllers/interpret.dart | 6 +-- lib/controllers/main_info.dart | 16 ++++---- .../import_helper.dart | 31 ++++++++-------- .../helpers/pb_configuration.dart | 37 ++++++++++--------- .../helpers/pb_configuration.g.dart | 28 ++++++++++++++ 5 files changed, 73 insertions(+), 45 deletions(-) create mode 100644 lib/interpret_and_optimize/helpers/pb_configuration.g.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 89dd0499..dca89e25 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; @@ -97,9 +98,8 @@ class Interpret { } Future _generateScreen(DesignScreen designScreen) async { - var currentContext = PBContext( - jsonConfigurations: - MainInfo().configurations ?? MainInfo().defaultConfigs); + var currentContext = + PBContext(PBConfiguration.fromJson(MainInfo().configurations)); var parentComponent = designScreen.designNode; diff --git a/lib/controllers/main_info.dart b/lib/controllers/main_info.dart index 6c0796c2..47e4d617 100644 --- a/lib/controllers/main_info.dart +++ b/lib/controllers/main_info.dart @@ -16,7 +16,7 @@ class MainInfo { /// Current working directory; contains the path from where the script was called Directory cwd; - Map configurations; + Map configurations; // the type of configuration you want to set, 'default' is default type. String configurationType; @@ -36,14 +36,12 @@ class MainInfo { /// Boolean that indicates whether a `styles` document is created. bool exportStyles; - Map defaultConfigs = { - 'default': { - 'widgetStyle': 'Material', - 'widgetType': 'Stateless', - 'widgetSpacing': 'Expanded', - 'layoutPrecedence': ['columns', 'rows', 'stack'], - 'state-management': 'None' - } + Map defaultConfigs = { + 'widgetStyle': 'Material', + 'widgetType': 'Stateless', + 'widgetSpacing': 'Expanded', + 'layoutPrecedence': ['columns', 'rows', 'stack'], + 'state-management': 'None' }; Map pbdf; diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index b83ed90a..76ac571d 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; class ImportHelper { /// Traverse the [node] tree, check if any nodes need importing, @@ -62,27 +63,27 @@ class ImportHelper { ///Iterating through the screens in a manner where, the screens that are ///dependent are processed first. -class IntermediateTopoIterator +class IntermediateTopoIterator implements Iterator { - List nodes; + List trees; E _currentElement; @override E get current => _currentElement; - IntermediateTopoIterator(this.nodes) { - nodes = topologicalSort(nodes); - if (nodes.isNotEmpty) { - _currentElement = nodes.removeAt(0); + IntermediateTopoIterator(this.trees) { + trees = topologicalSort(trees); + if (trees.isNotEmpty) { + _currentElement = trees[0]; } } - HashMap _inDegrees(List screens) { + HashMap _inDegrees(List trees) { var inDegree = HashMap(); - screens.forEach((screen) { - inDegree.putIfAbsent(screen, () => 0); - screen.dependentOn.forEach((dependent) { + trees.forEach((tree) { + inDegree.putIfAbsent(tree, () => 0); + tree.dependentsOn.forEach((dependent) { inDegree.update(dependent, (value) => value + 1, ifAbsent: () => 1); }); }); @@ -91,8 +92,8 @@ class IntermediateTopoIterator ///Performing topological sort in the on the screens that were received. List topologicalSort(List items) { - var ordered = []; - var noInDegrees = {}; + var ordered = []; + var noInDegrees = {}; var inDegrees = _inDegrees(items); inDegrees.forEach((key, value) { @@ -106,7 +107,7 @@ class IntermediateTopoIterator noInDegrees.remove(vertex); ordered.add(vertex); - vertex.dependentOn.forEach((dependent) { + vertex.dependentsOn.forEach((dependent) { inDegrees[dependent] = inDegrees[dependent] - 1; if (inDegrees[dependent] == 0) { noInDegrees.add(dependent); @@ -124,8 +125,8 @@ class IntermediateTopoIterator @override bool moveNext() { - if (screens.isNotEmpty && _currentElement != null) { - _currentElement = screens.removeAt(0); + if (trees.isNotEmpty) { + _currentElement = trees.removeAt(0); return true; } return false; diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.dart b/lib/interpret_and_optimize/helpers/pb_configuration.dart index 9ce92d84..1b2b4295 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.dart @@ -1,27 +1,28 @@ -import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:json_annotation/json_annotation.dart'; +part 'pb_configuration.g.dart'; +@JsonSerializable(nullable: true) class PBConfiguration { - PBConfiguration(Map defaultConfig, this.specificConfig) { - widgetStyle = defaultConfig['widgetStyle']; - widgetType = defaultConfig['widgetType']; - widgetSpacing = defaultConfig['widgetSpacing']; - layoutPrecedence = - defaultConfig['layoutPrecedence'] ?? ['column', 'row', 'stack']; - stateManagement = defaultConfig['stateManagement'] ?? 'provider'; - } + @JsonKey(defaultValue: 'Material') + final String widgetStyle; - String widgetStyle; + @JsonKey(defaultValue: 'Stateless') + final String widgetType; - String widgetType; + @JsonKey(defaultValue: 'Expanded') + final String widgetSpacing; - String widgetSpacing; + @JsonKey(defaultValue: 'None') + final String stateManagement; - String stateManagement; + @JsonKey(defaultValue: ['column', 'row', 'stack']) + final List layoutPrecedence; - List layoutPrecedence; - - Map specificConfig; - - // not sure why setConfigurations(), so replaced with this class variable Map configurations; + PBConfiguration(this.widgetStyle, this.widgetType, this.widgetSpacing, + this.stateManagement, this.layoutPrecedence); + + factory PBConfiguration.fromJson(Map json) => + _$PBConfigurationFromJson(json); + Map toJson() => _$PBConfigurationToJson(this); } diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart new file mode 100644 index 00000000..9fcef6f0 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart @@ -0,0 +1,28 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'pb_configuration.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PBConfiguration _$PBConfigurationFromJson(Map json) { + return PBConfiguration( + json['widgetStyle'] as String ?? 'Material', + json['widgetType'] as String ?? 'Stateless', + json['widgetSpacing'] as String ?? 'Expandeds', + json['stateManagement'] as String ?? 'None', + (json['layoutPrecedence'] as List)?.map((e) => e as String)?.toList() ?? + ['column', 'row', 'stacl'], + )..configurations = json['configurations'] as Map; +} + +Map _$PBConfigurationToJson(PBConfiguration instance) => + { + 'widgetStyle': instance.widgetStyle, + 'widgetType': instance.widgetType, + 'widgetSpacing': instance.widgetSpacing, + 'stateManagement': instance.stateManagement, + 'layoutPrecedence': instance.layoutPrecedence, + 'configurations': instance.configurations, + }; From 71b32101aa280d2977ab5ef72c6cc42d1330f8f3 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Thu, 13 May 2021 13:45:52 -0600 Subject: [PATCH 070/404] WIP moved the iterator to its own file and added a test that test the scenario of a cyclic graph. --- .../import_helper.dart | 75 ----------------- .../generators/util/topo_tree_iterator.dart | 82 +++++++++++++++++++ test/lib/generation/import_test.dart | 32 +++++++- 3 files changed, 111 insertions(+), 78 deletions(-) create mode 100644 lib/generation/generators/util/topo_tree_iterator.dart diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 76ac571d..12b529f0 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -1,5 +1,3 @@ -import 'dart:collection'; - import 'package:parabeac_core/eggs/injected_app_bar.dart'; import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; @@ -8,7 +6,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; class ImportHelper { /// Traverse the [node] tree, check if any nodes need importing, @@ -60,75 +57,3 @@ class ImportHelper { return imports; } } - -///Iterating through the screens in a manner where, the screens that are -///dependent are processed first. -class IntermediateTopoIterator - implements Iterator { - List trees; - - E _currentElement; - - @override - E get current => _currentElement; - - IntermediateTopoIterator(this.trees) { - trees = topologicalSort(trees); - if (trees.isNotEmpty) { - _currentElement = trees[0]; - } - } - - HashMap _inDegrees(List trees) { - var inDegree = HashMap(); - trees.forEach((tree) { - inDegree.putIfAbsent(tree, () => 0); - tree.dependentsOn.forEach((dependent) { - inDegree.update(dependent, (value) => value + 1, ifAbsent: () => 1); - }); - }); - return inDegree; - } - - ///Performing topological sort in the on the screens that were received. - List topologicalSort(List items) { - var ordered = []; - var noInDegrees = {}; - var inDegrees = _inDegrees(items); - - inDegrees.forEach((key, value) { - if (value == 0) { - noInDegrees.add(key); - } - }); - - while (noInDegrees.isNotEmpty) { - var vertex = noInDegrees.first; - noInDegrees.remove(vertex); - ordered.add(vertex); - - vertex.dependentsOn.forEach((dependent) { - inDegrees[dependent] = inDegrees[dependent] - 1; - if (inDegrees[dependent] == 0) { - noInDegrees.add(dependent); - } - }); - } - - if (_detectCycle(inDegrees)) {} - return ordered; - } - - bool _detectCycle(HashMap inDegrees) { - return inDegrees.values.where((element) => element > 0).isNotEmpty; - } - - @override - bool moveNext() { - if (trees.isNotEmpty) { - _currentElement = trees.removeAt(0); - return true; - } - return false; - } -} diff --git a/lib/generation/generators/util/topo_tree_iterator.dart b/lib/generation/generators/util/topo_tree_iterator.dart new file mode 100644 index 00000000..7a4af155 --- /dev/null +++ b/lib/generation/generators/util/topo_tree_iterator.dart @@ -0,0 +1,82 @@ +import 'dart:collection'; + +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + +///Iterating through the screens in a manner where, the screens that are +///dependent are processed first. +/// +///For example, assyme we have the following dependency graph: +/// t0 +/// / \ +/// t1 t2 +/// `tree1` is going to depend on `tree0` and `tree0` depends on `tree2`. +/// We should traverse the graph first processing `t1`, then `t0`, and finally `t2`. +class IntermediateTopoIterator + implements Iterator { + List trees; + + E _currentElement; + + @override + E get current => _currentElement; + + IntermediateTopoIterator(this.trees) { + trees = topologicalSort(trees); + if (trees.isNotEmpty) { + _currentElement = trees[0]; + } + } + + HashMap _inDegrees(List trees) { + var inDegree = HashMap(); + trees.forEach((tree) { + inDegree.putIfAbsent(tree, () => 0); + tree.dependentsOn.forEach((dependent) { + inDegree.update(dependent, (value) => value + 1, ifAbsent: () => 1); + }); + }); + return inDegree; + } + + ///Performing topological sort in the on the screens that were received. + List topologicalSort(List items) { + var ordered = []; + var noInDegrees = {}; + var inDegrees = _inDegrees(items); + + inDegrees.forEach((key, value) { + if (value == 0) { + noInDegrees.add(key); + } + }); + + while (noInDegrees.isNotEmpty) { + var vertex = noInDegrees.first; + noInDegrees.remove(vertex); + ordered.add(vertex); + + vertex.dependentsOn.forEach((dependent) { + inDegrees[dependent] = inDegrees[dependent] - 1; + if (inDegrees[dependent] == 0) { + noInDegrees.add(dependent); + } + }); + } + + if (_detectCycle(inDegrees)) {} + return ordered; + } + + bool _detectCycle(HashMap inDegrees) { + return inDegrees.values.where((element) => element > 0).isNotEmpty; + } + + @override + bool moveNext() { + if (trees.isNotEmpty) { + _currentElement = trees.removeAt(0); + return true; + } + return false; + } +} diff --git a/test/lib/generation/import_test.dart b/test/lib/generation/import_test.dart index 761a46b8..4b05d11b 100644 --- a/test/lib/generation/import_test.dart +++ b/test/lib/generation/import_test.dart @@ -1,5 +1,6 @@ import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; +import 'package:parabeac_core/generation/generators/util/topo_tree_iterator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:test/test.dart'; @@ -15,6 +16,8 @@ void main() { /// Three intermediateNodes that will generate import var importee1, importee2, importee3; var genCache; + + PBIntermediateTree tree0, tree1, tree2; group('Import test', () { setUp(() { iNodeWithImports = NodeMock(); @@ -24,6 +27,10 @@ void main() { importee3 = NodeMock(); genCache = PBGenCache(); + tree0 = PBIntermediateTree('Tree0'); + tree1 = PBIntermediateTree('Tree1'); + tree2 = PBIntermediateTree('Tree2'); + when(iNodeWithImports.UUID).thenReturn('00-00-00'); when(iNodeWithoutImports.UUID).thenReturn('00-01-00'); when(importee1.UUID).thenReturn('00-00-01'); @@ -45,12 +52,31 @@ void main() { /// t0 /// / \ /// t1 t2 - var tree0 = PBIntermediateTree('Tree0'); - var tree1 = PBIntermediateTree('Tree1'); - var tree2 = PBIntermediateTree('Tree2'); + tree1.dependentsOn.add(tree0); + tree0.dependentsOn.add(tree2); + pbIntermeidateTrees.addAll([tree0, tree2, tree1]); + + var dependencyIterator = + IntermediateTopoIterator(pbIntermeidateTrees); + var correctOrder = [tree1, tree0, tree2].iterator; + while (dependencyIterator.moveNext() && correctOrder.moveNext()) { + expect(dependencyIterator.current == correctOrder.current, true); + } + }); + + test('Testing cycles in the list [PBIntermediateTree] are processed', () { + ///[PBIntermediateTree]s that are going to be generated. The treees inside of the list + ///are dependent on each other, therefore, to ensure import availability, trees need to + ///be written in a certain manner. + var pbIntermeidateTrees = []; + /// a cycle between all three [PBIntermediateTree]s + /// t0 + /// / \ + /// t1---->t2 tree1.dependentsOn.add(tree0); tree0.dependentsOn.add(tree2); + tree2.dependentsOn.add(tree2); pbIntermeidateTrees.addAll([tree0, tree2, tree1]); var dependencyIterator = From bf81d01813596cf52185b489f44566b2b46e2025 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 13 May 2021 15:11:54 -0600 Subject: [PATCH 071/404] Added cast to map --- .../services/pb_platform_orientation_linker_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index be67b21a..4a3bb12b 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -205,7 +205,7 @@ class PBPlatformOrientationLinkerService { void _addBreakpoints(PBIntermediateTree tree) { if (MainInfo().configurations.containsKey('breakpoints')) { - Map bp = MainInfo().configurations['breakpoints']; + Map bp = MainInfo().configurations['breakpoints'].cast(); bp.forEach((key, value) { var cmd = AddConstantCommand(key, 'num', value.toString()); tree.rootNode.currentContext.project.genProjectData.commandQueue From 2cd4d20320f1ce5ad08a9ef13a421e7e34bf56ce Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 13 May 2021 20:19:06 -0600 Subject: [PATCH 072/404] Add constants import for breakpoints --- .../commands/responsive_layout_builder_command.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index d7dce464..f228146a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -24,6 +24,7 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { //TODO: use imports system to import material. See updated orientation builder command var template = ''' import 'package:flutter/material.dart'; + import '../constants/constants.dart'; class ResponsiveLayoutBuilder extends StatelessWidget { ${widgetVars} From c9536241a5eb816822c2439c5b12e432cb832c44 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 13 May 2021 20:30:50 -0600 Subject: [PATCH 073/404] Adding 'Breakpoint' to the end of constants. --- .../services/pb_platform_orientation_linker_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 4a3bb12b..26bba0a2 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -207,7 +207,7 @@ class PBPlatformOrientationLinkerService { if (MainInfo().configurations.containsKey('breakpoints')) { Map bp = MainInfo().configurations['breakpoints'].cast(); bp.forEach((key, value) { - var cmd = AddConstantCommand(key, 'num', value.toString()); + var cmd = AddConstantCommand(key + 'Breakpoint', 'num', value.toString()); tree.rootNode.currentContext.project.genProjectData.commandQueue .add(cmd); }); From e88d141447371dd9428a03323558de2afa922768 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Wed, 14 Apr 2021 22:52:05 -0700 Subject: [PATCH 074/404] update to a symbol test file --- test/assets/SymbolTest-simp.sketch | Bin 36255 -> 26490 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/assets/SymbolTest-simp.sketch b/test/assets/SymbolTest-simp.sketch index 1425c07c46cc7678c963205174ad24540fad6051..f4e0a330a854a711ef4d141d5b6f6e9fb94b2258 100644 GIT binary patch literal 26490 zcmeGCgLf@W^ezg=w(T9;$qsjH+uku(>}1EbZQHhO+qQG_{?7TnanGM{$GvOxTC2K7 zJzdqas^@&>Q!OtA3Wf#*0t5y0-{*qGGnpM02xvwI2nhb?+}PF#U~OXKL~r3}Yjdfs z;kYh}@XV&0I=$_7USdrO6yV!M6q|FE|p{_&*3x;Z`^Krcny2V`wL2En6^dSJt zl5%R))_p|)cVqrw!$X%eKKuHYnXuYsT!ZBe_{)>S=lj}WqXTY65LDIgcMz5Yg1rpg z+^p+>b`9&mh(9#rU!Lr#^KcO+da+|HdNlxieJ54bcyhhOtG$z~Hx_VV9k5|Gg7G>z zf3~cjHd{7t&QxK<2B*Iv8k~I|YF(5hn*V*Ag;oA9#*#MhKaAV_KAR4P%>@oZul7vU z=^OyJzin0F65t>B+e=gS17l3-&+iCm{FTdEanD6I47t}9e3n~DYQIX1HtJkiFD15x zR%;(n(0oxMb6$->9QxGB3jTdF!ln(+1_@Bxl%H-+57Pbhc__--rccw6W22K>Q}|d} z_?Iq6!H{mK89AMH1ap_ zasw$g1x_BKv?aeGl#vzpfcA$ON2Y;5WC(gs($!eQjxzP6CUFjS&>hNNVM~=4oC|+V z1`EHUnUg4~MtH+K!YU8Ko;Csn1D5;`q5-{anFa;&ov%%V77fWfga`#NI&I{LLAHp# zYQQfI0vW_1kH6i~OT3ISAz_?0 z?jz(WeFSwvLorE`{U$ST5#y%=?_sk#zBUyeLB#RC55(%?WQss!Vf4g8T)V;&FnOuS|{WL(gXn?CoR z^RTx!Y&+V$__MQ`bdm_u_iyL-p`%$FJE+ba=A2z)%1TU4K5O_mv^C0sg=#?mQH{qM z$gBD-ImGqT$!Zv+BR`)_lY&GGw;BHhc{Iw>`ExY3empS>O9}snew+<1&3eI8gFfBD z`4fc9^LE_UL`Nh=UGR^J-L7@FCZgZ%SvE)0Cf^pVg?g;zZ7UZf zK&7Vr{Wu|0=MoyFITa$ujJbN@2@@ z+LqEGDWB`C4th7QeAbe$V6p8U}*0G{cg4`8^vt4m9vluTi8v^XL5EChP z;bIdwsI9|B{)`10#t5?%MM@eoUiG$QBR50ef;fhi+`!OIQ5Galn1?CB#pysvU+>cWZELx~-bH0u+#yvumJ+re< z)6wSyh_Nb#-X<&)g=4LwYTTh|RwxT0+kg(6Dae3!_t|pg^{VygGnGA3pM2h;mR2vZ z{`{y2-wT}W!2tap=jv)}d}HF7BgV78E|uZR+?L}Aq)pViQr8-zt$1ui)#PA-Fq=%M zEv6Sy&9rk0(NFHkQs9}8y+mZm=NA;u)`4FU1IMcs_V2|kCTeVoFeK7~9ASK?Px0j? zIs#|fb(yruqUEVpSl}CgAI8yV=qrCG z;C}tFkU&Hd-4)G!27Lq)-xjwjHVd4&rs%T8zPiTMfB4t|8{YjKFz>-c=(1-PPV40e z(*NWSV8g;$3W7d}oN7-*5@bV#*02ge)E0>xjXwkwdnxP|%w-7KC4r$#oN&zvS_+rc zAUJ>$NZ`R-@Ehd}iBd;|?xn%xfqAPt!~C1Y5Ii0M*~ zK~UtwALWe@*`9#Jg(7(uRsw82`FpwN*E3W%@hy1~imcZOGn5;L)`X!36bzAy`H1jS z1({r{Yx`J5JslJQa+fbX7XeNN+pnyL`uR}8E!y7UAMWX5QEwq|Mq!Znr3z)!*c!V+ zJ+J7jW0a7gH9|?SDI6kZsWIAX`7EkkU0SU79Uz;8i|ak886N7+2xdvP#;N`{t(qtwyXD>w!o~{zfijGYASD_Jel; zY7#FrlU77SFIdNOq$I@qcjxDTINEX-Q4U(usxm*Z&hgIOkBv?~cfuLht05rYtMH{P z$v08;4^?$fIQVi1c=ih=GcYr8WMC0u7i1A;<)Hh+$t6t3 z%FHZ6_eVrXn2v>=nTwH?g_%u+gY$n;a2+kjb+cqMs_TnN z#%3LbWkm-`&eOw`;yrE34qMc-Fs2&}6)jto%bGq(pK<_|6&wp%n| z0iYSUfz{-eU-Mq-DH*g?=+n4qB$3qXWZv59+AQ9d0~x~28#83AGR>~_Ov9gTU=XW* zY17}miMZ)TX8GVmmXFU@(9+ji@$u`h8a23PbL>;4O($XA#&)7y2J0Efulel=%464v z^qqj&8*)ja?T+B4l5qoQkv*NfyqL%MhqAocqVMPo3(tYKCjGW(hUq_U0 ze18^S_dV{PKYJ))CZ9K-S-_}xrLtWb&0M){KHaE#uu&qjvgke@RRhoo&#A90(~brQ z8_d^V<)zci-%pL+pJBfKbnchH&Aisy>Z!)t02QtFSr=B9Yq6@;>kzjkcr~iB){?1* zVZ|cYlcLQ{7?3r@Mo=H26z=49WOPiNJ-c-hypHFE!a#gSX2q{?$*6L8nDC(;f`NH- zM&$Ldx^ieO{bp{2R`8f-20h$7x#wiab*H?A&JK$=yE(=g(^0LRj=M8lveaXzN(%4# ztk9?`!ed=@V%8qU){tu&vTuLP%)n=AGiMydnAfX^Afxg~q#WBYxv#Hsv`@a_S5c@^ zT)KSZX00++fv+zq-Pc~X@#Hve;&W9Ki=@04DfZe|XV+rAJeNt6 zFED)FqHZ_cFK(#dSEz4ub3T$X0GpVxXu&BI_?|D_XFH*sEX&R)v*Kovfje4a=h zwcVY%w0LLOb~XU}!XBKeLYIzjubb7`(xJ_Mn<>wPOAj~8ixC`ozaN?%?0H&I_4B%T8 zosL&{sy*5ATq+_vbk$tET-P%toDSnxb60=L<_~DLhcK-iyEyk2N4*3u>HLM~lnqNX z(5o4!gboJlr!GgpzY@o`(xuyZ%F_1~+f@C)Uh?ZL{qJqGe`81%ib=#?h8<&Y$^`Oh z4`!_raS4eubtMx>IhWSYX;@@oE{N(XLV%73zZBpM(RLaVQ@*-6jnX+{n~iVR5?Buy~s} zQvt!;WyCY1o);0kln$#W%QF&q<0H787f^(sK?%dnF3;>J*OPglV zwcKBBHbn$0IZ-ZB3z690o><`#`;aNx!_8NKeW#M&j9sy~qOB)Zuv%K}*X6TKHwJ_i zsQWEm{-MgtbgJri&Bq~d`f7?&a@ktTYpzdkbu=_ZItS;tA3GUYM~%_5P43n_JMUwC z=P>)kKsNci0>QG8_`HE*kd_}51r4;_4zlW*_Nkye z9>vgv?Xk(PyX14wJrt3|yfAZjzPL9imv}^>6I+9G;a##mAR8^?v)3y7P4Fp$Gogo3F=rB@<)#k(lSJ=WX|^iZngOXkF>o z=5?eV|0ce-;ZtO>O?0+bqYUe$K9jkddwDTcA_6T#n4$;>2+IVCb*Vsx!!W2)lsy~w zMgmL(SQ=IYT0V~bw7IfJ0GV8bEL!8ruK+5x3tRk}ZonMK`6~S2dVwe}ju38qf%)0q zX5FaPt!`FjcR=1Ukpj@`lKJn%OrfZ0%>A|$4t)6a(lRmrl+@&Vh)yu}hK`8(+|4hN z2W4s;CX=j1jde_p!p-q89$N^8mFubQ(EZrt%8z7K-kec)wpB?lPPKTo;E)(1p z{CVp$J}mjl>)1raNL0LDTEir3@=^qh?}jkmmts&BNuJd1|rV!0%T|YIRlAA7;Uz!Sb)o_*S1ugS#8G2m}R>lWADRSGiTT zA`Ls-@FVBS#8=8vOCThI^0Xal>P2#+xb+TR-PAr&nVcoMULj>ZrI7+t2#AA0b_~eM%1ik;HyoW|%xG zMfJ6C2sw`blS4<&un=mEQEza3N*aN`lZnN}?Ox-6uq}av-FoS0;;D-D-0_XZU2}K{ zL4+BCh(;#tLCZpB7WRZgCTte=EMSI)ra*A>W7|`eDyTIIDUgLUGLfwC3JHk@jhH1B z^~9Td+a%$OkO=@=6cqi1Wq(Cgx51U5AFYHU-k$1&b}Il@SNZ^jwt{NGBh^9J#|tt4bQ!+=qw6cOsCrb;zt|Ki|ut3-pu^<|)4gVtvfTFR70&5y84dd}J6XW&s9* z4!Y-?SwDt7bl}?nI!6%LU@3iST`$|`J$ynByha0R)ZT@DZ2fvqP;zw;*~LbJvu1nF zWp_<*@}O`16|!WiW+UbCuU}&9mwpijggpk_+``|4umK9zzq#wAZNu#Bh`Ug>%ZA(K zg>K^W-QN#h)BGFx5ia$qCe#hAp?|V`k*5j`p?oLv&~VZHrL@mJl-dRW*Zw`t55OlI zh>r4mXttmE74`Wl58edxQAr4CNV41?a>h5)daAAUUPj^gti&DT88N#oVq^|0HEtB|-LvhH<|l#3H!P z6&d1*7VTsWIExvZ z%uqNvH}?OuyYiIv%TgRfi}~|fDx=R= zwqAr@K5sKNAsf9pIGlTKIAz%kOCj%yd4%NC1*Ng$IO%ve9!^_pwan0Pc~xKF1rZ^OAN6rJ2F*M3aKv6xXQqc7 zSSH|!O2m?c(~}wf8-URc$J{df@#(1C`uNe_i0lRUqrTso1c-uM6rs(5Ra5f+fxjjc zFc~s&o+HZ(;rTQsRKm_6=J!J)SA(EXzf_rTb>G8w%=t7D}hsB~3sQ&{6 zVu!X{)rW@`cKcOjpoB@5{Ya4#=r`innm0vGt^*T~{`5W>7%mtB)GhY5e0s%!6 z{@-&!VG%}QHcl2+Iw2-bPC8aDQBFFpKcZZ8LLBVOjO@(9>`WYN|0@?%Uw7DOLHUhf{rR**`B5k^`cO|*1q<}Xql3boChwEb=~BXL#c}4;wTk`1P3gthx+E87(PeIK9PVNl&F^?V_B#5Wry@Vu=Z(@s9B z$v0KC;ly=SX~bdv9)G&n?ia1-C`e6PKm%agd;o&-;UU@3*ZrfL4{9m2sPn6pQqF z)^C@~ox9jhj5-+8yG&a`P3z)FSUH+X~KFbCNYT-omlW#C{Va~WgYF&C*8(( zo(d@=76iSie`Wzj#+I@}JP82c9=<0Gn47z%vvusE+}=5=%3n370yWx;H9Qfn4%>mp zW;eC}>@BU0k`~4-_WWtby3#MC=C7ZCQkY4DDmO{2?GuKL&g-+VBVrT&U8oWk0Fylm zht{cTvxhUaT&>*1)1T{%Z*2|aYOA$@%ciTUIqu(QB^%nUYl<$E;jSjH*VeHFc$9lL z@ZY=tMo^44&5iKunWm%HTCEuC*rzbE(zWt-NtlbAkgCVV?4T*PxGSu%T%=d6n?Y2P za(SuWRAB1v)@^Llt8y09?(2qdPP&?en_Ap+=)8)2fy-IC=a2_CNK(?8Q_2V0w&eo7H7vLV%bo zNI@tI&Dqt0HoH*z!*WDQ4T2<#B!vciYeibUknO|N#K|K+o-#d)1{tJpDehO=KU{l_&$F9 z(NLYbWclr92xxfdk>Ex7yGgVK#ME=cG@>ytLh!6vb2JPNvqQZY^ii-0eMSPA z28t_Q=*&MiS`tbJE>YdFd|FeoM=a3ZZ!f=(eYq^ccr*+#^FAz?kZ=X*T{R5(3sDKY z8?e<9#RCW7}@ z5nW>p#_R>UVHlhPIHR=vQZU_fT75afz#*iyd$6yA2cC&O{fnsb=~0;c9?Y0Tq0wu^ zm=Qyghhi~*G3>#&BGHp#y{q!-Tt21Z* zhJ5VeRA|pED(8m86)_axu=U7?a8(Qc{5E8QvVeGbvaTPz$`LD}w;dn)D}~3UWidyv zVst)~Lj!)G-cJ;REXDr~zroSGGv^q-akOU=FO*hMSf(+GA1cPquv^3vSJ|jhKfC79 zKEF^vo&1P1@`2fi?Y};viV*5bP!>;bS?_-W1E6>x)7D}xaSxI6*n9$bBMG(EgEZ3# z0Bh9{&`fZwkj9?3Wf6)hoM?vV$;N6d*+l>08Z?Hu)F|G(-Y>x{+{!pGeX?Mb<`Kqa zkL9}qFKNN6irg}H*Gs+YHV&)Q#9PIMKTaQ1vlgZy+*;=Ex8GL9O#vTsb=9CI+6kA* ztk%>?&V17{SKarx-@PndW2Gs2U(2eSnvV~jp7y_dU5$q<OZg`=}pzh z%XEWPosVJr?#B6^GI4#Guc`x=x(fa5RFVClyL7s*PB1B|v(z!?b?c~P-kR*Kg?}2{ zymn{okmDC7jID6Qo>sSshg|wmGuOynPf^&_4*KW=sRc|Q4zHYRO?58OP#lnj#9eri zUulnqS4pl1?{ceZ3c;1TKg=BGb~`Gn3&u{_m3KqpcL4% z+QocIOlZlBpAk;G_sL#}s5jcQ&Crv!?LSrr-Mb4dx)~cDr6gYEzIJAF3c+scuc!O& z>5b)mp;)mmsSvyTLC1t|kpDAio7G?gvHr-g{-anV!HX?^@7B_opf3~kFH`+~}9n%oDm*3B4Dqm1V zr>!x0HEB?;#;cTRQC9v0u!&!Q3SW{MUqj)en|1I6#-tqn$@uPJj6}xG!-ttb!OeHL zTUA7qnDwK(EUG0h@oK~Yc^*6vi_kZ2t%>3zN&97%+@g+%V+bszENDsJ6Gfs)UdqQ4 z6}ch3`p?Hf43&FRdmfGNZy0Up0G@9cjJh!FsPex+W!N@d<%iKbFGJ!-V0rM~pe!QE8hyN9 z(OX=JH^yUKoK9Tm0!{>0w#>rU(CTbO6-(p+avEDc!2jpm9S5035P<*zNrU~bxwAHL zGWegl%Z!(>U1vo4_YFHukeuG~B5H3=FXPX8Qb-45EgPsAN30+i(DU7y(B5N>S8x(Z zQhME)%HjEEaRy*5jH^to!qHKMO;J|%FAtz%uAA6a(bPcSgkxqtYy9`$)1VGZY8Sf^ zZLnblMT6U)37CGo(l z*{2^a&9ZcA!+K*%#ne(jDj{}z&Wp=GDyViV*72eZ%6sSW>e)xf{9fC z(HqB+^FT&7!u8^$r`^?kVYV@XJZTzK`?_H&!bka$NP@o!E&3 z9oLSd?dyjs_5kE_?sIx21#5F;ky0~(wg~%MtczY;2*_)8G86$9qBOTO_!U{KZ{t6 zJ1-9nBX(12Quw@kDM}unJG9ugHJy~_+Pt?vJ~W0d@@h$@>@%Vx%0#krx={`}nWx^4 zmrFT%eSSTi4dsiFjEZ@vp8RdbNhhI?DgJgRA3d?v#kpXU@i^SLLWzlqnDr??1SB&! zpG_ZS+X{{SJzWs_J!s&mUB|_x^L^8LaBIO7eEq+c5zzmBNvhq1spPK!5RlQ&7wx}2 z90wC;a}yUwhW}ll|KR|@Mgke#q4Kg~@Gv+qKW*S8#Dx`sfPiIzfItSIAbx7hVpb)8 z{(v17#r^qgg{^wmad_q#{-D2GeBhg1~LSqg!H01z-3(n+&`d3Uk#A21{VAU{e0yF1bU zs_W2*IP1ZT9DZtjcMf=cfk2>)sRZmyp@$BjhOrS)JBL6`AIZ_9(E<5i z-?ZRRQ?$J)cs~##PB+A#UO+TpkTNvK%Clxb8vHT_pVI7{Y&_fPfw6pdR~x@@AqIv_A^XZ8kMOILXFlRoRnl zk`@#c{Qkz=(uelwBaDr^6Cp8yEwoyhSLEI!pu&Dq#v0Yb1pVr;^52;luUny2o*p}$ zYdvtHI^B>hJ0plaqk5JQS(K)#wn~`0J7kAd0IGa&QWG~53vjB&p{SH{iAyTF9vKsP zROCB@p~8I~M#{+qpMk|-O8$9#=-FURbT`@NR$uUARobOK6Z9l5TWo{%yqD-%5~~Xu zgs6iiF`@PPMfqp|@ji6rnjFbRsl!s|8Pk#?{i}+akLpFqEL*uhwx}sNKUb6+Rz6jK zfi1Oml{_mV_*GbVd7hqe%nYR*<*Gz(buVLXy`_QC`Q$UFg!`jPSC2BX<#$5cDQ{|t zEYD|Osc1jTJl-Q2e^gj+-i)e|u*xqOk+^ukV3f z*&e(;EsLM3DdKWoD^&db74_8>ar#Cq&t&CiRkyiZ;Iueg=<%BS=?Wf?)&|t8ae{tv zeCI;{RvJOz)4dSUTAf|3UuOj-Ij%Yq=#ovWGr1j?mAGzvuUPcMnf>d5!jmpZTpB&q z$0UcvHxtV1y-p#D8K_3T~^3JSFv)xrVm5A}IjO^$H?AqvU zPqgLC)nU11hNM5;rlx*-KDRd~VVhq|YwFcL`1i&BAO~qc?kIMj6+OYTt^oZ)>3r3kunBW?62kSDn{gEf6b9Yt%Gqm0|NImSRzORCIJd zFXGN34@ctvRwb9lVzBLcO{!3@&9lWWFDomkt5Zy(*I9ek^vbDTKIQ)XTjaRd;Pu*v zpR~H;uB;)bNikR=o?ODkC3zydn+V{vy^l;PI%29+Ea~{y=qCz!?K|G;3%@Y>bs$I8 z1k343oUV;0hQG2z=VIzdI-XcEmPpN@^GRwbecQ>dt+=088o7RcJ^P%%P8ts->)kq< z>$NI6Zvv8U6edw#H`%&l9j7y6dFY1m92++5-z(>40Pz~ z#ThZVeX2TL1Y&sIv?>4&83fLXl+e38x-5NBoiO-5zF#_i%P*#e6iK zwhvOxGU*84Zp023=4F$4pI3ysoGvimkIISP^u9m!9D4s@j$ZpbzjxhczYGvN%uhCt zoEH1k+iIT$T>E@`)Qys-k3=|5B}QMiXK&c`N7lU_r9aE$MFX1qGF`T)An{yl@Vq9> z3d~1QUT;M(A7tXgA^XeplCGlY9GGa1VuOD?5CO(7v+xBaszdbMJv1(yt(R$^y$p7_ zdS_KlO&kud@B5>4`!xRV*QJ)D*6rcvL>=cX4X63np>&(5>C2A!CRxVCX>dR~>b+IIpR-Nka- zssye#g006{9wx7Mhj+`}Tfd$++KTv)p6r4ZnWKXMVh<&*wR0(82dQOU{b zac-XL#s)hvrLb=@QUv*6YNA;P%j5D*&Y*iWFz8oe%XeRo^EvJVY{@yQYS9%>qz zt6y7=h=cKH7Z(@rsww(a0{U_UUv9R)=^^o*ays7DEbaO82&Cr(mt_Hw%#Y$Pq|rRo z<4JVk(-hy8?c0jO#kk4R+o<$L1$yX*o#`K=FL!r!2L@JJKH}CMQyH!HldKv3GaQ=& zge4vl%kL1}xVqWJKi18{Ajb?>L1ABzl5%u8B!HhJ%=i}KdaqzPJXX^tSUUQmjx?CG zKhAWC14TU9MEjOn0h0|%w`mihhc2d;No5wH@BRqGvUuC*N90F&`gcVQi$NPBM(9Bc zQDmcgJ`IY!wzjs{TiW@&CB=u`_n95dPw#PY>(`>1I`JGzkrm-r4Vh!pb%^2ieyPFi z{y#ksFES?N0s9tt~Z^GyWJlixBf9}$}v307Ukn3;BK%+PU$$ef6Pw* zG{H85edmVz`~utI3vnu5NtTQ2W0o>;wf=ZSNsbra8T0~ceb(gjsd+kKUiLjm+y2$W zKBKBo_xZaj*(}?G{%gVq%1S)vU?e|kbn|I6NE6rp*laS5uHJN-z(46eXY}Uvq3$p_ zu>1vXYLMdLV{*+dO#X~-#LB(0813{_oVau)wuHZ_GXtP z5Xs8UUJ2km+})Y%;gDl&boSm_=au2IEP1Xo6k(!a%(qE^_O#uev@VYy7m>#9?x@Wtili@pc zxhIl#4hHF#2tj^o40CXB3}-*y-?#(F@t@z$tE&OFB%KY~W@ch7$~xB{4|znJo13=) z(9dc|mCl5O%GRh8f#c!xd#RsbUG0A0Y|hI0d+5L^%RRoy=kuIO0$#>ipjzO;4r&h3 zQ~%jjg`{)wpRW5=*ZXy}nu}cD1qFYr`c>C)R+kA5A^jbb^;$z$_HZQO^0PYO!eV3+ zVU|x<$8+a(=sw%Z6#^y|-*pFJ$kvnEvcq(iebh$#o8h3^*It01vJTe-9ab%QOxZ`zTHYzIzVJicx6FlD`;R?YSue{Q1O$O>x8Plwz# zXT0YeQjVy3-9Df>W5O*TjJu$`oh;Don?0LjA^~k&&Kb>voV-lXzj^FJs_w^{crWKNn=n@XB=~O1tEv&2h?Dvj~=5OHL zuRk1P9CG|JPTv;H7ftI`yGz(Ix2ky69T{DEqYbN`dW&tX3CbOrlTs;7zCWBFgj#he zT$4mm_0hM1^)mKRYQ9sTnyetbC*8K`h=8wj{`BV_Ds84R*q%Ax`U$HdcZ*yGJnu$* zMwhf~7hROty)I3Xb?Ac$Z%ezX$NRve;{~66x{i6*2OHNR`!5-t;0*Nt2Nh&E|VZ99dJ ztc_R}bD#X~XJv8A`zl4nMpLyR(dlr^qyIADWRua&KZ#K-YMSX!qpNU$cx{g5$Ef7e z{)N)?FL3Zf-_rU&gmqTN-fF55SOhT+V#|PoL%;H zE7Ig3(sPbYPsfhp)~oyv;g;i=phY=vcl)OL3C_-~dGY7sGw=C+gx{=uTRz{P#(M+M zck7l_q1E&64clJNybc4%!Nb|M(9Qibg4Khs5A)wqm%~vlT z8KyN~mRa}MRD^Dq`jc6&M}9vBgA~D<5TT^9PQFt}9@}f~B8hL}1@y>FX8u--`aXkp zIOC9oHgFTyj-S7AKT0(_EXLGBu}x&!5mhwJX-49E&cJqXXlZWS+L2jCs{WpbcQ{N` zdzL8#_O|21KdbfmFsg(l&32q>br{0lj)V1n=GMA~!1jlCT*1`qeLt%i+E^5PC~)*~%SBF|YXdZxsG-_N{G7 zu1CuGhV!UprG%kKTnaim8sXhujgK zAl;k-De9q2qVVkw*|Fg1gk4g-kyYl?$!S`MPQuu#OPh(DW3QvtMAa1~2fLD*^X2P8hEi9hv7roVSY19nReB%WZoT0^T#S>eDwy0? zozoL-+QWRGx?N00k=~zJ0j}5gg5_%rm@lCcM6w&Gq*m|sjaf~Xbz30U~)&z=HExvZsP5gJ9nf~ydWj1O(hQpgbK1B%y7Y1lR@XX|I6EyFX7i7KsrV#@Nxc7aWXF8H;_UPY2I_r9 zh$F#9?yGG$!YHli5^7s_i7%8PjQv&55SLYTtEf6lW|BAwoL4T+xU@Z)g_MF%^JqxL ztH^v|PK8KFU6S(hiIf7n{QV~j@Dps?=&bpFtIi?IWrh|{4_Hyc?qbu!%@tDT)-^O{mq;J!`0hOD?pnQL%IZ*4A*wyjGC+VKiPQ8@i)dnqlKeLx@)23bQ|J1PmVs_HM*#A^8(;s219)9{ismuHa*FYQb zBV>Rv|4dJ+wJXFAPW)$hMJ5Jh{|RdvKS9Z=pXEQC<`0ezmh?w<^PBjg2&TAMf=wo@nbIF zPUNyOQSr?acWgc@S717}@HRoeHi%Og!8XrVMRVOH+8;K7>j{kt_cO&@4PT!YoppJN zI5ErvUguwu(|GXQx2DHd*i0H)EI`K?#Ws#S%&yL@oG!6XBPD5-o)Me!{_6 zQnAsvBXSLlKMBM>KkMS7QbxNDnY7GgBjr|6QFwi4t0{3}Az` zNpy&g&P@IhyHFV>5(#TG>Gd$D#sD?NQ)OnY{yw8eg1@%DZZf+EJ~z7>J1jMkXC2}D zC1_=?L0nl$$6V&zun;WsoR$`=i2TRt>Z6sIXVqyNYq{4GUThIk$pz?sX|kD&HMv@y z{2pV1m=$tI1Bzi0$Xd5e_=q6|*QN8s^rNMAAJ$+t+y)zZiig%s#7*SoUn)|v)nM46 zflRzi6A$ft4qe<;dsesnGOI@cw^iRcuwc*!3K8dhIf1>olakD{d6hOc`*goIeb652 zj1Eh9I>umBG=U1m;o*hKc(Ds`Z>roP)OcRH+2SIbeJKVT{oam1)}onLcs`_?6THIr z$)TZom#4-`^Cmg>_M6>K2(b^?3riAzV~7+pHy+-MAjhoQ<9)$NEU9H-k-M>H=2vmL z>l#QD${V>-xBgQMhz8Uq`RbeZcm3igwV%k<@<5ixEC8!h(xdrohmg-uQD z=9+b!UlqsLXH~$T4RJvVVlM}Cdv*)mOYk{}%dq>UQNqokJ;`pJKy`|$QW@ukD zi!(5KI-f5gxmBf6=2)m^B{W`d90JQ#kI@4oX$pCSVvF;xPBT5(oCfiW#G3?sfJG#p zvVNQ^YAS~En5L(to3$ZEljxJyy0=uH%iyY6HU?{i^wrC}&l#D0<9pB9Ja7ZP{Q^=e z|8puK?h^_xi@vYFpN#$l9p={7k^AxA4O#F;Ly~SUp!r@4hnjO6D{2A8ZSY>U@CG`V zPJ(bm@a*I}*)u%F><#T3Xf%4F3e4jkmn_43H z74~RQ1^^GI6Tc|9?D`{6?wdAU_0Kof1tFQ@RFzr-TmZoWS@?SS?LcMy-jj(k*Bv1u zI-DK?96}rq!GD%fhNG}C*>96a>rABjkLm_)2vCPkUn^<)M)%vaJKts2`yH0V)u321 ztAjpjkT@NWr=oVNe6)w6)3HG6o34!_N553zbw4Lu>qN^TPal*SKh@9Mga81*gF2Qo zS4ni$zvbXfgi;|LFQE;&PJIcbje%u3&`9`W6N~Kn(%L5xNO;|#kDtAu`+Nj@Dkpf^ z;7Bf@9LPAQ?py>M*0<64+THv#9IQ>Qw}ViEh1q%II8ee(13D!{fz!~p()4!s9tv#L zDy#6`)Q=3$<(SeE+T?$*9G-29HM^abn(hf)tHUiMfhQ$M-u*P?1;4Dunwpvh8~HZ} zbNz~m%lm7_c9{x919PN;rfyDY;H5M=2{qp1KYGQBX0K%;!&#OLU02}qdNV#0W_1uI zrPBK}EwA}3;1%JmGMkr3uotY3ZtsHF%nE{1ycSz}R$6zy!#7?^ z3nrL*URyqV1Ku*;j9e>-tJ~$`ogd%t4#)Subi4rULU)ixo8D$l)Dlg0XqIkg>aIe|lVSl@arQUX$(bkmKCOvAj$-jpGm9h|phre9Z7~N)G zMVx1Sp7S{`bJq6uhLtvY*U;QJ9Kh0c;qHg_IoCJ~corkKeth=uSh+4ou%Be>5Pw%l zcBm?Z$fS?A5ji=YiEq-$0#v{Cr6N16HLs3Pk<#e9ZuAb`c-zRP{?fHRdKLbHJqF9F6c z8*aQ`)6B~x;N;nOX7WF!&#uPuk2dH+qy1)LE#pP|BI!Hs?-G&MI|ppsiMIZ1pv>YR zqqD+qr|sIS;|#Q<)^e5#jo?MJPT$%qep5;-zc|upZd3jBe{Ngf8ug~*6|0?))OVf= z{k{K?6dM7zzQT3U^vmNFmiaisUg_Rc@INEQQM~pG-)jC>C2>k#1fg;!Pf#>(e|i+p zt-~Juc>n4i_!}_Ovp{-0ngdzTXE+qV`G2){?%`0i?;dw5B%wq(jYBA8iX_Gu9prTu z9n_ein3tLuIfgkXp@<5ZB8Ccy=v8uvaS9=)$WWM^&!=%13^TvSe)n&`@9z5ju50f< z_8silwp3igN_xi57LN)<<&xBgVGlDPjZA9`K#D?Z5Og!=xc84#& zKU_6zmr;#4i)+FwIm4v2=@mB{Muj&yd3${1a8|vlW{yRTz6ZG>6?kaVxf6 z;i9vpY{mmS5&LXbcMZF{^Cf@83AOa?6Cdcggy#ox9p`702*~;Fa=ACy57XT~1;P26}Ur*V{uNk|qH7P2uc4%qgy0B^$(%DFe^4 zW}{g$V1hppzlEFcHb7$&T*#o^;ng{Vt$aIgE&p+0{n^z$mEj-vFu>yHONipW$cGMs zrT38)D*NyvJaxX8f)GO1Uc*(1AiEc?mW>V@G(!}X9KR&z`@p#CH||o#;~laS4kk`Y zuC)zb;B1Gv4qtfJGNC)3LRL{9Ix1Ln<>2zlKHaNWERvOcdJFvzp6QK~sBTl2R4zz+ zB}mJ0F*2Iz&D2e3Qz&{3S33y>$xecB$EDkYiY2};#`_l~X@N122rH+BSDxQko^b0P z3tCpE_8?dwJ%#v=A|o(;nz6;Xb|RutI|}+S`_bH`_C5?b`<>Hqbq^7sMcD0%n)l@N z+#S}HD$OkJ{Q=W)(#8bapm2YVhS)pq-vvTBtv&WkC*> zXz@g5npQeY{TcB7iH2G9mW5=ST{YGb%)7LUShw*g<{rkMp|^#DQ672C$V0kvqAiX2 zf&(fw`47FUqGz-jODRXY^8y$zEeEFeqT1SFqz_)(Y|-&ggLVvIE(S`PA#P{(b%}aJ zB4J)<3&U4F7pgo@oC~}b!M0tz15?!!&oROb9crCFf_-gbW^8OcdAAorBnmX1<1HlI z=!+1qiP`lm0IiCecaWJz<}i(ObFp`^N;*<0edhddrrm?e+#uc01~cbxK+&DynTdme z?G8*=l@NBS!`G61y_8bsz~ee?e6ud-kaV?}%K-~^#`D9?kNW!TjElo;Wvw348vWL{ zv_r!x#an{gt@*|zPMJ?^V{=LT2B?|mz}dVffji$5b&ej4#%kPXROWj{th|$I!&eFK zt%|?hn@G)ir#

S1B86TjZiA*mUYSSJ?zKnK%|e+%6#Rq*{J0B1z|@WlNr&vZV39bz98>!e6z1}Z5xH3W^lO2heL%%m02pNIf z$+O>fTrr+ZZnz`3>t%7VzVE_mxZ%j8_RxDf>#kR{;f6?%@lZ#hdKd-#axo^5^>B+l z2(%TehK323{m@J{cF~go!RamN_P(m{hR=_5u!|>19dmUywzi6(Vj;6+0+q;&%6slN`xceb-utZMLN8Z^)tyIrfZV#ZM3UpU4XEH5L0z~&*1uF=U*BJ{807B$ z#v*Y^v-PU4o15E1OBKsY*ueGUWan5*mAc_XoP=ZUz|kXL9N!wT@e}S|RZ+Ti{#5_u zBT$qYr?k130L{wHjrGTsKE8g`_nISX)n%NK8NNDN=*y2vZ#b88psxb#ufbDG>N2=)&?kfAOrs!29u_N{NO+gYMdE-WCDrI z?ZS*C4c^HmDzhtEhXPjV&3DEEs~lBZ4jC*;t2T5X-FIiqOi%B?QXkaqE-O^a7W7}t zPyHye>MZJ7NeTdqm|?=btsjE+SkX`QV#3 zUUSNb*z|PetI}UlJPqo*i^0Is#xm^-H#>f#gg@}nFAMs z(VO^!Yq;mg3Z$=vi9l3pDV{Oc%hp*}?v_g3p7(ZKj=?XVgoq1cP`d~NQJl~B6jJm* z>JQz=QIsvs<3HcxpHy{Rs~qX~<^;?)Qdi!vjL0M2ly!^k)Twlw^vUVIaE_d6&{!II z5UZM`*bonu?8&C}?2=j_bJpsqU2Zlc)|Yo_`Dy2x4Cc4%$-mF4$YjM@8;+fNy0Y|x zF+q1wii)!I8te;^(KxHNEWemo0V)*6o`?qF#x$% zjDK&!BbT}dc(wGee@C#FV-?QIMYZ7|!#_GYRA`*B(_^EfqNv26+0^jC7HgTEx?{0V zdwpr}xuOe>0Xorv%6J?Ow^31J$j)Xd`|brJykc|N?Cr_ChNc_%Jaebj1$P%hg`VQ| z->ro|DuNhwlr-$TrU16eIyC=^?1$|iC3om8mlq_aYLZC>Rz!#W{8|#$GV&8=h4FUS`u~9 zPj7zGd$7xuLMANrA~n}qS8g~aThZv3Yl`TP%{5CkavqH(^f0MG9@k%JUyr!hF9}nQ}K(xml<{h zsGRiow|;ioU-;#Y-KnQdNw&2U1B-jJVFwW-xkkhOHf%7AYj)ic92kQCaF?Vdi~lSd zLEqg0r7n0msIRv0bC4=wFQ#gVbMshtv*|KAbuPHty`V>vRJinD?&oKf#Opg9VL0~M zP5ILzU++uls6`{0WeEuhg>~6&Y?Vn?kijJEo6aft6Gpq8b?pa3PEm7Bh;`6ZQTSvj z4Skt2jDHIA?=60JX{PzjWpagiDs*viF%{Qb+xEt1-Vrj9;6>WnQ?@!whdkn4q9gcl zmfabzkJF?&BFGw7<3l4QLWfYW!46%zBpQD>Ckf)$sp?Ye8HZ+8sIXv*zUmip;=rB* zauu9W6GNGUzLc5HKb$M2X4)nab((hKoHJu7wf6bOsou?JrN!>Q;Lu|KtDmmw?61UGloF> z6X+8${BU?ro=K+#f^oNMV1H79TxmxN>j$q$jrV>LgP*~oPl9Ulb7^Q2d|KNQO=)DB z6a9+tE1l46--!19n$rPV&tkjiePPlbF>u4TA7$_@+6vKxI7uI&Zh`tGl`Rw%G$-``Q1;sDS(-KvN?vg>7np?cM^mE3bBL6*F@BZ!SQQ zU}WucrQq@wKxrojtg--vmGj^S^MWHU?2pWW+%i~;4NpgPvp7pm%MPnkS1Hc>cvjTP zrCh1!Yg)Y;pTcx|zn{S2#0+g9n&pS{W=3fAo6bgXxD#i6aOA?82HNJPk#>KzfQtgK zk+8QYzQKbl)v;SJ4`-IR7RQCnwj)vdLWpQIR3)4IG6>W(Vo@=cINs-Ee{(~n914u4 z4jEfKUzM$4AZxxB#Nmt~=Cw%IRc5LrdhgiO@$RpNa=V zPhBaG2dE3iT?8hxL2rZzb$EF*^5&L6R7<4h+U1gMgz@SSOMN3HWAO5f1g2{~qfNRP zRRhW%WpY(W3{%xl=EGy~I}5fRfz2sfgd{(|G~G4u2HvF4>h`P{SXpU19RDewiv`|c z&@F>ykYBg`z>FT$UGUpm?3bC?uRl7a6>}V?Pur8zkg0pW?T7tn)Toae7AulCdvI>< zx#z`_!5cCaB!TVExvV=?Y6rXMn{CFAE+7g3W zBM)fHJAsDJ2-R|T5x1vLY5BZE&AcCZa~=ASnDkCS8_K)Dx^NiVrBu0u!(dX){ak1AD>RWGp?-hmV^t8$`=C z9d5SaX1CdVQZ@&N&GB$^PT8DBH_2fWmj3Vf@PRTk2M7a*ZD;}f4L&)LS^uBvEnlT| zz)mhxW2;j+C!B8Em~#U`i+}$CmyKhATFHNIE`R@=%de)tN>gvx{Aqd_d=chpJx9~{$a!H d&rMnRUyDK5m~YuoeBjy&ercdd%P<@N{sBQUv5x=% literal 36255 zcmcG#19&BCx9=Nu><&Acv2EM7ZQHhOci3Ua=-B8a9a|mS_Dy=NZ+~mwv(Mf8KF>L+ zCv(nvYrYy|RMq(Z>YZ|upkOFKAV82nAAhf}%Mz>5KtO~dKtOQs`$o2g&ep~@PBa#d zwl*hP>W)~f$gh+%JP;Zyp=)+F?3Sc7BMr2zuSO%9S}^R@)OJe@82kR%p*c2i)!bv6r+asP`5RufAbA|}g>+pT4-RZLt z-wC<0opHnbd$0jSh_5_-mUtFj&huASgPAa^CG1SX>UsIyhMKK{P6vrq`@q{+V+)JON3~VYkykdvIRIT%jfgk2cn)#B z5bm-HdeGa3O>?nFp^Rk6P61z$@QO%914YIQ(j8d4*JYqN)1EdNKGuwvhBHB;WYvdB zM#T?E5y&P$a%q$XU@@sQK^G3#!ORR}U`8bvG02!o-;( z?p`Bz1>`cEe9DIp0AdXwu+xf2gC$Df`!Qu@#^$NKy2A28sLolDi|8NP1!PgkfO4*D z!G~*t^hvQciKr|J(}GVhe?ec1mY&Nbh73P0;&+=CVk}buu0UPy@Ssq`IcT5R4Le`d zuVxOHWkBEg}7a$R| z49ft~VfX-PRM8xgQi8pi5jr~7lkDVM1MHrZ*-@gP?4ZIWl3=P5JbzvyO1Rs}DO!-( zJmDU>RGGCAB1lnray#=XY_~AhAv2ofI>cMM`-FT`wI84a&k5hYj~trZmNnBJmGAnr zl(RLRsCJ@{-QVhOy{v{lTsNO+Khzw=MPoCB2Q$9_K6^RQ~Emjeq{ zg9ek2#Ouqc_|G{c^is>H>t`Y%9FD{LixOxvF!?{ykJI2g?wmO8ZhuMw$4}k)0zSrK z;iF2EY2k7OLgaOEWoxXhnt0i7v$-B|P{x&VET52*@ViECsMmn-SDL>8FGHaKfsh!e zTmoZ|1B<)%OlQhX>r=l;)5dp;pO4C)Iz>{!a#E$`SrOJA+B2m6dYdQ#S*(OSQmQvd zveuv|wx-mQ(Fc-Zr_iDYKu2)w4E-s9#qq!rmvksD- zW-87#i^4z(VTd)Wh;|}KloPDvLxYOOC98XsjS~glHS?km((v)i_7J_eLhc~-LRtLt3 z(pzbp(%Muu`m414VT7J@#x`YMFXJAI5XRLc^uML~Dky z)rdlP5f4Qz(@?@D$Lz*yD zqK#ZCv$vYtEKknM3F4{HS8bf0w2zK?y@3qVQe{4D`ro=3e*bDYGj}*^k_S;1Wu+_< z^Kv21P>6u()xvP({EB>U)&cJHb_Cuq^jHPvzbcJu_UMo}o>HTD@~I%fJ|B`^09s;( ze?Hd9dUdnjaM5PUishwVDZtJ@DjfEF9Mh;ET&$D~`Hld|TGUkaG4cI6q(kj$Dslc= zLvA{v(&^4?3%YD>Yhkp0`#mE?bt^ww{Ae$70r*lnT}ePrl^=M!T~x+AieNjMULLhj zCRW(0=kY8)Tr8m%oEVdPGe%)s09LPeRI^fvZpI6g|4CrzjK*dQri}dajGaKzHuMO5 zki38Nz^EKSVahd-K8g;C2d`W%@Bvo%$#nqY<4fNib#JdXXjBef)>o{x*er0bjo(w0h@Ar1N4ch6O30o(SCj5OgXY6D9EO3#F7{pJ=G=?M#cQoeXlQ_uh0;U^D^Z zhJz6LLmyYt^Ngqwh9cL#ShRv*%qk=v$ggipYn5R8(PwZf$i4Va%NEBp~3C!p6`hu zi7JlawiYI&Ha*&=`0I!XU%hk+%cECP=hQxZr7ZV=Mh>}bQIpPeT^t!vA2EFSt}`~! zzeW~e?#yUeWu&9<)t(~7mX?EuVqSIK1h{%!tEoK#Ql=qKON>e*_ocET6B=y^R|tsl zlu^7jcN9=CM39X6Q=)i&4c-q}icJ|x5`_3oq< zjd8Z*%@uj9Eo?($>htZ_qWN(M5)4bJ>g^~*eSm6F3n*!<^QjDFmQy8X#M7SO^}VQj zCmf+Jo(X3ccv`A&*i;5xZ{Jo|h$oO{;S?hYc?9&7bqsqFLX5xz-;YouE%$+0;Dwbk z^W76;|1~?2;BY367$ZA0L?ycyVwvk_>J7}vSLCqUlOp|C;|tM=-mn== z53)jiki>8C-&XHeUe6-oH|AA&bzYtoJHTh#&2KtrsyM6K+FCW47a6X64;EaS$^s5v zUs!jGjQuIM>!JMQ9%8(&fq}g+M=??54;<68Lq*BZ%P= z$mlg}VVMe!Uk8-Yk(LL(x!Oocz&?37F6nm-h_TfodG>iBP6mdBN07SOEd7wRe{pnS zziY;|wfSx{(ip?je^u4a*-D?j>g)N#A_9WMbEQt_4MFZd<-t(W5;7<6dGMwZ5D@Kq z9&D#?YV1hMD9FOkD8$4{Ex^VuM9sv&AWSVFEGR_H$il!*$Hd6MEX>OGcc#4Tu*`=1 zlAM$SM{5HX))o)=v9)TH5W$@ux>|}t-HkktQc6&|kdyT4jnx*Okd3(*&g~LH8xv$% zFzIdgC3=5kdzvYF#NpDTHe%1jfhm0__wwp3-P{?O4}ZGH5IA+nRoRcN2>((L2S8HN zlO<1@MB~IUel^p#*qThfNikeEY$+5&B92KsZ{m{TD>XVxL0dL_6v;*{t({0xo}B)Y zgg$)cuF`*S(h^%-l5ik1mg(hTZW0&}E1sV9&E&F$Vook@fVJ2yF-h62J)#bC)VnS~ z!i#Bmlh`XQiFM?Pi<(rrTbxjDzLn1S(lcSqIVV{ei4+r(YN4?WuVSd&CH=feYx~G) z7oDWT3oA9%0~p5>YQBhErZ&>+@^Qo{gEn@HN`2tM!dXj2QAsDmqJ^*AiMvVrR$~Tl zt+#jvtD7)10`h4{{(C6f1^Xq@2AN#X)ruVB_(tN`u9?C2%Hs9P3a=uZ`t{$dUnX=| zr02gDu&S7oGMZiHu4|y)u0GvlqYl^VDl;l1p^r3|wRX3m3s-J*dws${l43lmf9M#p zZZi4pQWz}08(EgKN0F`^`8e(TatHp})2wI-`_-#_x#^)|(N9?Gkl&qGOMSJlRe*{3 z$%MLeFLCHw7*ZaRYK#!gGzR;3lgX~1Md7dg`Z)C?kCJ4ci-y6@(^M261# z>FsA?1?9n>rL|ecH+NtiCDgh3ki@gOm7>6_9t|Orp97D@jn-N!HAbwizP3 zEga0spCZ1t+4_g;<_7>C2A^USrY_C5u| zkMY9WkQ0HAB-n)5eh8#K=)M(fno~=BaDB;5{<7^yCw&nI^a+4*oXDSr_&B=9mY|S;?l&|Tx4LBhs6ym$dBGZqLYsP1Cbsc{-kIF7WHU&tn-~r4HEQ^f0)i5qQ8=7Xi@(UZ zMO_;h4yWmCp9ef@{A3`lVhOL59Ly3Vl6nj)acsHyB!4J%d8|=$wc+$eVaFTP04qtk zV`m2^rj{_6tUFeM+HPgZ+ldL)Ewnpv>AikODyZPTHpj&~Z0-%T zYref6wA@>*Ek|T9pwL}~o}O(fqQJkU+ui5&FymCJ>#9MoiQ_NOgKETK zGS<=EEY5)4P`xc`c@NDmO3gE*aw;;7SykJYCpSFfd{SF!#o2+-=_9B_bX10nm)R%8 zQ^YghdGbdifF*Bboa!FGS2?IqKk!GFxQ04=J<p4+a2a$Zwc$eiR6+|3Po-k^X& zBzbvrn5Fhgic8hc%Qh6Wg|%O~i!XHQ)CTq{6?F$_I9p8VrXv}|ifLQ7W%a9Pt*Op< zryfkecy$D7x8q@U^aDWxV!!n?AAWF4w^gz&d}m)vG%bRab0U zrh(xiz%wJZ4g~4wRF>^Lifty8)tB?FK61`N>K%sKOI>}sCL!A_cU`3AgNwKZ_W%x| z_E1ar=a99nJ;)zogcR|SF6%eXb~w@;oz9%?X=3_GvoV4`5UazUS)i(00`?31mdV`j zYz9P_1+Nde!rx!tNgoOq+t!Dxy`FV7C1aLfIk5Vqv|ZIRA$T4xamm~{fuE}`=cQKS zs(H{%vhcDz*TE7Dryq>qU4y4<7!L&Rpk=14rh&iI`s`nM|A2>{9R{F+kXCUc8<~UgrC2`o^cm&){6c$IHFr9{gL6tIe+cB)(~nDSgh(SR!P0 zg5k|6%<7Sd;n)$`fH<`vTKbz8ny2AI7b$OEx*O^TLt_mt-R1-sy2CKLKEl!Xe0(98 z3<4abG8{y!$?xh>72$*bi49k$)Ft+3gryxtreYsJU+E z+X4z+g7WilhgTzxLll+AnFI>ew@%&)9!q<|z4A0X^&It%?V$ft|$43OPC5Wn#J@~0~TSTyXH_YliNp&W6<)RyamX)b~{9OpOklxF7X#DI~$(Scw&=o zZ6(cf*8?LEOgdz?Hic0XVY6_H53mJ271{Cv~oEJ%IIVXv0jxr-4w6%VAst zuT_nlc^RIIt!T};%l#@=GBB)_jy0g-^N6^Mn}PMG8xgX$p)H|;u5Oym4$8PlWU`qa(PT(0HI}ehCi@dtA9~$IAFnP;BI5<7Sd^R5#Y~_bRtgk74~oe!-ZCG$^Ap)2#pv5Vp1`{x5=H ztuieX4xQhVL(VIYZ?ilu)$Wj(_cM_%H)dx|yew6n9+50>5dS%I7JqwdZUqMdy2Acv z<}4&kC&bLg$V4qj&&Ed0#4f@{%`PCqPA$mF!a&EuAjCq?%KTU6tfuL>+>H84iOYjU z&L6TSk|85SfwgVF`uy`T~M`h**YLj2P_)B4DT@d!P8WjW`PlU16z+j8w8MCtvwg4q&R?$c1x z?vBB3CDoa_GsAhjtJiyH66LtyUs?tsE_KI zW3*#gaKXstE^>b?6e>7r$kTM0taHbVUnb2YemkFY<;Q^iLQ%3o@{>o z&RmZFOLj1f*0c*po`oCZWzNlByE~!NC&MeFX?)2Bbv@^RtZ+$z+iF=?!_~s>K`1w% zA|T`P_p&GPSfl(oQK^ZS;t~HiXq6K;7dLz-=l!Q2MZ@qxJ#HR^<@DIhCsTRR7i z$EL#Ux3Ntdk5E5}6K;e5h!u+$@~a~gu1Q@|=kFOMq_Hx{Z^=8%DP>2{{4PDPG2YTc z!j?hd-MH%?2@U%+fu#tPdQ_|mlNkaG`b|rYZyHID_%i@kg=^8aZ3O0ivA3m?i9WKw zIK7&Wa?Lf-r|hX06G+*kUf(t*tW4(8t<0Ogj?NIwSh)3(dsZ(z4bc5b(!BLcpk*v5 zuLKP|VOOAjaYqTVmJ^;$3$c#;gJcW(b)j$M5+s2^6O-Q&R_vk4|Pl^14a$VLIx9G z1KvQ6=7m1?3&rga9k6HutujGUX!+BA^<$JgbdKGDD`SEpMR#Oy)T#y1rR(D;U3AAe z`;%Nzo?2~zgc32iAQ&@btK$N?3z+SGAKcHhlszE6Ih9~HfoYVK@6I7%6HYe;Whccy zu2V$c;DU=JyKu}R;(K`07JR*h2(U*(>l5@rMk;|~;TO+(B)ceBxf0|JY{(6jk|FhM zoWD?3<0=|G(LJ2J_vYpUh>Dv5-EmJ4%m4`5`#EkG zmL`63j|0{-C28}!Q%N1# z+L0##MK9KnPbVjzEQS#bf zitfyWxl@(WjZO+EJ{=+#0*+|1xbgs4fv}OqjuS(%N(wgmr0x{7zaMTrjGFIA){3?H zQOg~;`=RBOGi_K+m16C1GAtPH^Hn$0dgGT>I=)>rG~jT|rz}>xqJ=v-N#VP;e6P&$E?>!tO?b9_KKRniIgHa#709(UC6`jn>C*`ulKWC#hFz z7&E7`ZRsF2bSI02>}OkLRSxYuFyosxELL0t81V627oWa1(_`=dzJh!^OS}nKcphYb zL|f_LinuMdt}&}3Mqx7)tQ$e`b|du(@Tkhb5d$)*Fs&^E{4UQX+fbo(8+`3?=JuJ% zRJF>`)+DV(FCNv9m3`g$w5Y4Yr9a-@*5zgkxi)by6G&1~tlP}=sTW7kfg#{7H)JYx z;&RQ49dR};4b)cF_{Hj0V>{N+vtG@adP?MWR@R#EVD!0|GXa5D3^Z~06^#SAm{BLg zPriXsUe_x%(bcu<$#w(r{dyuGS;mG+sGaLmn^`@$KCe(6c^;RCP`s`$XY8zw&_zdv znE_y7XiS6C&GmeNBdcH6GjjyRYti&e-x8QWs170@B#e(HT!$CfG+@|3A*sg7`bABH zS6opZWzk~gzAJBN#+s5OjllhoC(S`O(b?qtc93g&I=>t$aQqfZLSUdVr%34w{MUUD z=?*z%o*v*OB&cWEl+}PET_CM{>*cq7si!(Nk63YpRP}9>e zLKFAxT<#owyZSoOHvr89paa+%SU_`e0cfR+ZA_ia0L<@23IJLWb1Nrfhxd0YeJ5if zV?$dbV*n2iw4;-QvA#958?bg9JxmWBV({H-1S^T)w3e7=D+SFeMN@d7(5Fxp36$pt zoh3gx8@C^x?(5xS7<2_3LIPo5iwyjj;c^TRE0ofMID(Ko!P%$lX|Rr3S+q}Q?`(>xfz1JsKUn#hy_ZER!o_ekGAeN6CURv+*5%NDEPoXU+S)k1A9n(#A&S`U19Y08P60 z0(ur^06n`l^t-A4?&hP~zf3IWU~8yo>;%w!??p%iK&$lbIDj^QR?ybU)=c7+wvyYs16@O!Qs|Wahb@J3YNb zY@qJ;l*Z4fb(yMDj>K{9%{QKaRgefA2wHfSh0BKoeFr2-v92GJ;SKEPbuu|a2t5N@ z9#nn>!B$_D)$O-k%GTkuRFdtyFY3QA+n92qTIJRyGY`XqIIbCVjsu7{1GL-(t)O%VnrR<}+!i$AHvJ~>gJ+ckUW zTwKTXQGDSZ@_16dAUPh-;g8BuU$;80plwG3x+T)c#Hs5@RtBoK2It$^sE|Da09}3p zs$a{x!VR&~N$A^zC54GRKDKfM&b6eW+-H5t4Y2*$8Nz;-K63h`!dZ;Y>rW_-%4jUS zQ~a%1QfPD(7Cv>{=;aRaZL5pjd~CRvDl4}O{UUf@S$;nWDk$8nHJHm^Esn+rI>>i+ z!xw{v6av#H+Y-ghSr^DVm|d<}9Ae0p8%U54l*oqH1H}7C6OkTzsH4rSGQP?&mciq7 z?-371E5c?&il0Dn_ZBwR$bmSY3bSB6$f_FzIS#_Rco4IK!T9vrqGqaElP04T^$ z3=uR1ltv81oDZy)pJxFGnxB3F*d@@y4rs>TV**SjfW;163rw{O&JG6FPm~Wjq+5~> zc+KA>=uL3$S+(QX0s#KHLIOqu*jRCpM&L&&Y2fH`FW$^seO%iDon&_@*B8 z4Xkq@s$kuoL`c3NNYF_UHAt)rA%QqGB48wZ%Xor9kW%4{IQT-WAJJm*_S>M~p?Ugg z7-$2STcPSv8wM)+a|RN0vuTEDDpKgXEGCGI{tp2~2D3HAYNQpsE>J8;nbFjJDtfVc zn$@W_pbPrPoY?S#U6`BLc0SD*S`0SK-@%#?=A&Buj(XuXNG{ykDArKU0uZ_#&kelr zJD`2BeR0=g@di3cNn{dH#6yVC6^O{w>;09)EeNzpxJlaa6NfpBL>(~H`E+Ez6XgPQi4hWb<&wxq zP-G>rg#{L6*d>1Ox%0UT7Ae4$*vzPvrL|;h$hHf4OL)_YCNid8rEU#ZCYHxrCLg7G z63Zsdr@E%<(&Uor;`>Ux7C$$G$anK~EBY5ytK^An)c0@)iwkGuCmVzrWEg}S1a30- z%M-UH_$M?W%a-yTR8J8X;eQdBE^?o0u9vRoSTbIs!x3dIe40)?=)cC>Z@-2zCN|dG zA=|;;`La{@Qvtk(PVb&k0kbG7F{(8x_KIou$N1LxGE0@Y&RZLK@&knpg;z2`vPm*< za%`EDvh6I&Y<8J-nd}Um1&M{e#iGU2EKPaz__uM_obha3rnl|q(8KDMaF6Cki<{m< z?!&|{8DBcSV17~llFBr|jG1ARF`TiJvBxx6Z>9m$0H(2{vDctOmz;h&s$@c37s;Mi z`TgV@^(0T>YB_hMVM(2uX@N}Lug}^EG@7jZOv}&}vRq|(fJo34fxrLpg zotnNsyCwijdXfB@-6eSud7b(>`UM+?gk|yNlN1FS1)KwHhK=?S7d%^B;tAr> z!_tZiGiyqEE#vj$u$H@KBuwSZt%Ld1E9&YMB6DBad%1?Z3fwavC}FrG)grUeR?&2+ zPN)>AkErm}$<;rpS=S#{KlU#5Wmsw(dJl$JY#G-5Dqh`fs4S&kcj-Lw=FHHpUPWt_ zX&t|Xza@Agd7_8l4s{D{hre5Jav^IC@}5OH+TUpYbrH1%LF!3bGcEpYJzM=3`7gL% z1u(Ga=jb!k7!H&68_n1b@iay>QMzt+c{9q($y*vnkE7D_(R(g^)_toB+>0;GPm~Cf z2=StkgGt{K_r8q7=!B(Ksm7~TH6`2`oLQWG237&J4_yc*0;U4N1H%A?{K*-tw;Q;-H2{xxN|#7$1`R~uSPh6{PC7Dbdv9HMAXkQwek?Zwy8@BQ|A;R}zla)xA|8 zR!47xPTGrZi=JG6yFj|GtRA#nsihmJ>nu)u|E*oQGkTeS+0?3f+@YecX|IQ19%~d^ z&rnj^E>UG6I{WRg@X-HDY{qW;p=Z-c_R`?;eCN8g?=)~UXg>rGE(&&=@6er`WhK9L zzy8WbMeq1g{$Wd}sjsfD(23YZ{J3baXwhI#tn)1A%sgueYZ6OObizQ*mi?gZ%kLXO z&(Gxta*PE(?!nmb*)KK+@A1xZV7V6EBfQHFNMCYq8z(d(H1g(F=E55bST@YD5PT6CjvmUP>crDhzde=xz54sw zh<|F8&czRh(&hH2XXVs#)9>usoZi{q?I$5G(Q~-1IVrlwKIR7vXV&cpc6Bc)Ta_^# zpS<@TwV!C$Zd<%}V&1Z`KqJ8)PiZ{rsUuN&;O-kFZkH60Ajn{>l#)dQt(!M1>RLS;!8ZRBE6sZ?E6s;5;k9vq&^{Bb- zKOc!oo!$!WB!6wZOP(yx^>KY_H#HdUJGY!XO6QeWE9qc=oV&H&Guq#tb~QgM{uZ%T z-obn8|C0A)cs&?@a4dT-o17cX>*@vdeCbAFZL+(57j*UXzb4&(($GJtHVZw&ztYu@ z#P*}?JqH#S6co^RG&TZ!q_7GA?SFlR{-3G&zf#)2^YQ;qmr%#h!+_Ak2H!oQ+FC() zid%WEltFG1KrHr^lCiA}tDoOxmKhDD4tmB`q*dpytBRC<1u*pW&6s5xMXiwe3eOmb z4)lVMEL$yYA{h_Ja6%Jd=Y68WN4RWyRwJvn6JZ?PSMKMyj)7TmXXoK|2=Me23TSQj zat+S0lY6px1R`!Fg#9lp@iF?3S<^Ez{l_fn|1SGT`Tr*Zg#K^E@gEB0kDdM@L7@Lg z5O$Ui1@aGp@TcDYDG9;=p#P%~|FZ_6|Cd+)AtdSlXqEq7X;4SkKnK#H2;ceiVjwtfBb&C`N-&th;&{e4RJ7tkZVhj{6euZ#OK<|H3yP6LvH>n!2Yt9;QOOAD_hgQG_~X3V*1~j z^xxx=ex+q$`f$_7#>CDJU}R(aQ~IYKBi%b>__y)@nCL&d>%+kRHsW7K zmC?6;M+W~Jqg&~lzI*lEdLK0f-th;tCN&EK8-SXT?HzzHurj^J5)0FNEQ!Czfw>{S zjj5IK`_O3l9SuL=3OybB`_4y?AA29mo!+U3zMYt{xv7~GH0%2ni&oLe*jnYIirQbL z0A@y(_xdiTe>?`Rfit z|8CoNqy4wwt5VI=N>SZ|cW>oL6xm?#3{kN8S9Er06)2HCG6v{C6=D`2GROiHqv2N2 zAP}gepMD%Pq_gIBdW?!j=`4@ZO|1Ov_nBFGr`|17#hHR-^91G+46 z*ve2z?MIui&HmwVt03r;Tho}E)qcO5-g5j5Y}i%2d@V=51uN%b&B!A>6cl z--$W30`!9g>2&+p)cqHw#H)Q+y4Qf-DjRdHDtZSVQf?Q^fA!I(cjN*L^rRT zD@*mI7z7iK-S9PMnD|c8MkJ4F`U9}xe!dzUM5%D=#1UwH2i2XFg%HFajz}oF83i?> z)RyQcVl7nR_?*}?k;44&qFyS3hIf56=hT>xJZFVZlx%13Q;Ikx*lod|SXU=U9LX;& zgUBjRWzo>$?5=(*I2*_GBXZ6)e&_x9@RzpI6y`+^O)~z1NexPS!@lU`0AeFjGWUA5 z8RAUp3Y19tQVb21M2lwFajJvGfckxM^I63(&>N))@!5%u)JCnkEE)590bGb9+=*5t z$;AjIa6vUGOXbQ4P>WV7eK2-aviB9QSN#Dxu&B)GTq<1}aRQcEc!_9&OH-2&C2pU| zDTTO;K<&AeQ#P+LhbhkmG{6m~Ow6_|G+Qn^e#-QM{UVVRW*|3~Qau>})x?rCRSe97 zJJyW)<~XUb9xS>6;)Re}Z>3DDs3X;;7Dtz?fhfb$F646UQ0ybLjLt>ld4Ynv26-|Z z+9(HgPzqsP37vp5BiP?9C)J3>j9=^UBP(1y)E|gR+D06&xVdY;G~bHU99My}FwMyz z6aF(Y9Hi3kMyEnajfO&T2)@W+c*0l~rBud#oyCs)^(gVw_*}~E*xBT6#A{r|GnR?X zgRS6<>GYJgtb|`=vs4u9%F6<_CvJ%=u~K9k>Qd;15PC&rL$o-Y7*iK&iK5IC9NYma zUuOvj(u3X-CwQ{UXvOrR>0{x;rV~zlyVzOFyA7+qd|nI=a5^NXrd*cus^oyCDN43` z_Qb)-VppS3rk-7yD`~@py9FYlHMkNooHCtZljpS~`9fy_JtV zQL-3j!)W1>zZ|UrGYJezHe;VUhm1JafIqBT3?4q*O^Wt{6{%ZBE0U`gWksb^N$Y|o z)hOy4eD4ByUq@Ah&y$beCt442fi#PRH>uMn$`o}UCW44J$@5-{cY(wVORe81I|@{R zLrfjLl2U^9^Xt@C4IBm|Dhk8>o@_Heaiv3;WjR{eeI}$gRhT4wsnaDf>bsHbKxUXb zV;Bshq^?z2f~)7t>b!nwUs1imx^Y=h*mU$3QIFj>!>irl<9Skx-j&cW5hPx0pAAA{ zCSi91lC1$b08*l1=P1f2E&m5Lg`Q`9Yq8A20f;2U*~3DfaDK%uIREYlbGm^a^7(^{Mq4(N~uq$hp+b_MGO>_ z8`w;TVRkBJqi7J(e0p$-qn z%|wvL2}UB($;i+SKHlK;k#=0n&@p|%n80nQ1}eK*hi2qVHfb!S7zPA2(qc77?!)7Pq_F1X%joBv|^AhC|gBGwrUwPVrc;`5(|K2{9l z0J;9EAT3Em{DpN{1a~wqMpsFjhOMs4#Lm!eG}ISza72_=oGKk7Rh5RF?lTPTbtk=2OIRy6P7S_wY;FSYBhQEvv0Pxo9WpoLx+ql z(vt?Ya|5nZ((Ty|)pH>W;JM4vYm*aJ#+vFe-s$ZlO&3)czNqZ-sJu!ZNvcWfsyuz) zocc!IRJeMY+_368P31p*Zq3h$qeO8D)_QqHn1gPszg4{0zfhCd#`T3@bDQVgVfPBP zGzA?F1E~NT6bzko_UD2}{f0slL~?G8N}{>aUN(kzBl@`c8o$wO*|*bhXbRsV&?>Xe z?)Y=j#CPn1LD%zH_uH@D_uo+Eu)5yXY;4P5p;Pc$?NEHy5?-Q0+xD;F)9KzDmf<;Z za$AMZo!)bJV9u=ktb_36ty4Z$K-nU>*K2qouYE`CcGj>w{loS2#pDLwcAZz-Thz<$ zW^=T^YiXQa)Aadyt$qG2+TpbSz|*cJ`cq;y2x?cnbA-4&N3wb9$ZXyez6aNK?`^IZ zQ4iiK($(HL?<)(g(aU}D;!od!0IHr-5>T06!JrEZ&A})8XeyGVsud}{?gv@aM9f0^ zH4KuUo+61!gk;x#RjL>dhqM&;1`Mz5Ne>}R%V^iyE6>gx7)&);V;L?JEcbAKkvY8# z^7PdFUC4`!hl7O)-zQ4w5j%^97x??`$93~;S!{IlVBU@U3t{KW;}6vo1qg?MaJjpm zzjRw424V_4iy2NYhLhv9e-))K_S-!T#f_-jH`BJY+{SXYHYnzuTyzk|ixIA+_IJ{u zADOI+acIU7=c=kHL7<}*A-$8)CgyRaWNQ4Z9ImeFFyeB8pna6-?zUraj6BmQAklB; zrBv!a^38%o%p4H{D(>6hUL`l2TQMD7Tbpd*y2{~GISraV0e#Zv*ZX?Q0u0cC48W_x zC%O~#+#4koxE1@Xv z1SU&9=VOPf!K}!Zrps?;B{R#8_&$oGg^JTX4_K_WN{OkYcRKraNjNrZt){*XSriyA z1;-(#9Gp2T2IvCDd46(AlVYI=l|f2!t+n6V#-=J7D#c_}bI{n)*hTZdSoRxbYTg~> z=(P9RETi2--H%E@GaU^pSJ6^XCpP@J?t?oCqK~&Xm#pb0w1w}hZ`NHo3^yLIxrjv& zdhFd;8`>Oh==@!SWN6v6tNmo!;pn7iax#wf8cFu-T32dR{u>&!QDWMY^)Q#({@Peo zr#~nUTH;Z9zNRNt4ug9vcr(|{gUchdztOqZbXwQ~yxFaMFL~18;PznOY2NzvqT9dY zigf-p=4cNBeD1YnaU}A*Hyjpg7+6WOz>k_ttfLTwFk05tiEa+*c>mH3|d`{i@sFy>FJRY=o5)Llc*1VbAq|4>cpW+XXtRb`?m zbaMmO9s2IdZ&qne8Ob&fcvpuQoE2|JK-W!&HjP_J#r@i?43of}9S z3piWW)ze-Iuam2iUVTc&_=B1Ut{-89Eayrl0p)qffw&U(L)3)QK9bvu2 z_pNfA=iyM5_u*Lk@f!e+2TsWj-{+-$3!-WaR&gmArF?f3T8wy7zBZ z!ovQasRSFt|C@6BMJE31*LU6huGar!`@=U_-f0vI<6qo^@ttSypa0mr2rVOb+vp|-V(!D4Zplk|3?{1dwpX?KRoF-!hXhJhcYf7%}ydBs{-N zJBm2`r-*#Cr+-RVp*NR|S|Zs;3yMAK(lW-aQOPDfghj9oXzR4&|!wR9!Djir3X!AJ9^y zP_LI|t$a^i+c>&y<2^^!)HM=LF=RJ~m}{r>R!J{ulYi(Efz{h-o${ry(C$ssYoSu&+T#M=Vmf8>U)- z4ZNVIsNBdxver&iKhm#jq1hO@PhzpSi%R96%pqK$fRcMAEn>{EwN2buG(LB<_Bw~HH&Yh7UE+l5r%rGY6ED0X%mQ$)f zFcz1HEb^kDSaN3jT9(huF6iSwiCk<(_|7b_3QNxQFspEoQIW{HtR{2nXA+7cT)?O) z+C0Dq<=~fu2EQWC`DY+XDJ{MA%x{^cwibNC3 z3K#<5vjbb?X}~o=Egbn$av45^Nviy+1pLc4ayDoti=IUD1zxz5z|zM6uoTQIb4YuI zYQfAb$JQ@i9F&aY-YbZ>)Op3iFcDSig5AVQFw5(=9_*H;;X=a{t{jA$3PcN`bk5zZ zx_l?udnsijcc=A$lggmcn6V2pkTfL%m|-#Fb#Iuwaxea*-k=PRurxKD){F!YiJ`^sRk5;x_q=ArP&?@5pzI zLq^7hj#~>xxl7M(h2_tgqdbFub`~7rmSOPKz;%$18hi;%z_CjOhBYIwOvZe=9@E&e z2Og7ME|QGXrf&v{OM7_p|7q{L!Vg(fyloF995C|re zPy!Z;io#YDlqxoCG?89H5m2du^b!FfbO<4#gd}%`v)y~k-uImI?tAzC@veO2%gS7H zjM>H-bIvh-W3D){h+dHb=!Vg48{jhET8*^NS;w5I-GI4u6EOVTrGK%Udm7wP<-b=X zMfUw3SM!Tw;!ba*25rfnBd2Uix5b`B|;mwM))Tc)wV) zTYS(b5iGfFH_vUqbUJnB;F}tkGpRUvD{;*Z|Ifn$g?9KgB~Qt&C!a1!W*8ae z$A?}dDvh`B}X6>9nw^d7r zYtK^++U6I_0tf7bttfA9pCa$v7I5|0+xQ7=@r}kAZ?@sB!ww?B=)wr3izJ@xvqvnN zVH}tec|2e7%cdbLMrC%OExfrm!2U@yZN4ugG5P^Rn$S^UK(+mFv+jQJnkXL!DeIV` zp-$n#Vp9vV_sCnP!!%(%IUg0!DqHe`PTlM4T-w(@{cO?PDtM>R-sD>M%(6-!uy$$q zAu+4VE=3cq3s&9@>nx5i3oHA++=GSz-DA6lyvcxI?m?{ZdILs>(T z$I;2L@iE^bA0s}8NAAhGYa+s`8BDv>Mnp56DNAB}%DVlFRjQO)!p+1{3-nfYy4M8{ zM*cTH`q)r&zfg?ui&*t%>`Yn#uZ4{UHk*FRMMG&pAq{ z9_np=lhK&!C!MbJD-TIpUKa{FhS7Nmwr3 zLxu0`#DHD-pI{Sv^epMw&=~!eU~D5b-0cT+-F>~s zNCN_bfI%=20tAJCz=(4okP`6!N6zo={XGZ+BN)sO4pV^{8yKs=peS_}eI(de1!8Cj zF+v(64Up>k`(a?Pk@^7`Tm@l(0&*fjFckxRLxhR}0%Z(Gs3VMw^fk0gM@TxQzi0c4fl@G*qU_|@%g5atuHpxU!T*{D|7#zpBLL_5YFc$JIN-oy20jIl=D>xAGw}2&>{q}8Z3k`#0MRA;0dNnwXK=_Nh95?g?$nZN2P`uTjYVr^Ezt;xHiNV^hC<_G*5b$Fq zR!Bhu0{)Rjz~3~1i^}+e(Vv^^^aJW-Rc!(kJOBU+(CQ!XKHN5~bOsoriay+r=S5;{{qGvC>87y?&Uhl7CZ+%PM1FF%YUFpqe-*xOl7CSV{E8`($_aq0VWlsAq-|@qz_eB04N|oROVkv9SZSZ6uSR6 zG6wtqTEtdK!k-_HRk!}DLh{eVc(ni>fPxP|^id!cBoqR~(i_1b+_eQt1p(7Xsp}&l z1|UOyt^k4mX9UR1;~>_@apigauG{`=dJ6eJCPTm3+W))s6i5|<0G3a15K0{c_^82f zpk==)F5ngv4nYBHNF)MSIs$rXzrugg zl$x5KvE%A`Ky?EUQ$Snd9PPPNpwCJwcXkBKtw zwJNuWe`7`ee^msL_~StuJy1UBSY93;-CuZk1c6nHH{KDqvMRZM$1Gw8ctaKG@B{q2 z4|j)j3(n?-%dFSNjB3Yk7}dKg82zm&EO1^U)Sxr0LT1B(n7--7(Y6x^d6VSJsCAj? zpb*Tab2d`0r(brYdGz{0&6uoMznBIafI(~+_mpB78;FQw-;USVFCg&qXGwYD^w7JYsQ=W`>1{z!gHrqSki z!+aBa9y{J0t28I?&JV{1W-N*wd-v^Drm@-=(PtO#lx;a@q!QP`f4$4(L*FKiy$uAv zn{wdVP<4(7pFO7ho#Bq^>mPwnn+@cKQd6JG1jaypV_y!`s>^7qv0)H80m~b zAA(gQnqo&NscWwv(m>X?Wyz9<>C1!Qhw)MLQ7ufc?(%15QP;0`?!W_hQ*Bd*lJ($u zXh>I*%|s|&x3)~FR_=%bnE%mZzAc{(AgAT!Td$@|Zf1QAB3_WE^B!MY9+o6`IP<*J zuBblL{TcmO;-wMX-peCe9eobh`@}O{kDg6CwoZ4aA7|~4qZeMCS>FYWUifdL$6Z&h zj9%j1BT?OQ5}_QS@n0{LX}zsn=Y~i$f}TLSOLkOmd!2g&qva|wM3PJudFKA=OfNM* zkkV7BeeKgcaYxy@o%iwiZ_ZwO>IO0m-M1}08m4?C_Hm)p=B$k_Aj>OHwDS*b%-L=@ zI%#Qk9=~p<^UaH&>~=p5ld%5<8try)Ys_`Agzc&^h2;#@PsdVA=Xxbv7%>V^bI?c8 zd)D#?Usi*j_z7=r{;)GlX|0;ao=&N&vNL@|;jeG`4uYS;+MBkDqw#n2PJCOlH_63- z2CId$C+XqHF1XKB`kJKc_tu;1scZ;`QBKJA^X)didEyn^q^?IE6VA^WJK$Mh6oxpM zdiD4NB?G;^LcES=4nDw#ZK{mhrB!05g^unhQeNI3w)bF4j+m&k-k}fyE=L;q{LB^T;Lk)~{9;d3aekX)?LTZfZh6Cp{)by{jq4 zy*;d@Xj($~326|#w~FaKinb%=n~sfo*y?I_}JLQ_bNO*B;X^#Jwft&=>KmQs-7Osyd)L9<{QUN zO*XFI4jeYgv+>YDqmw*5yuLg7U|&FJ3$l56+X`AT`RvqvChSNdFXp zce0niIN@~Sy06g&eDe3#D5tD7$T}{muV-{d^yOYTmCKJMHhZ_PeRKJ|&1QYQ6MA>{ z9=>i1)+ih-{Brwa9^V@aDeecFDu-` z{){z}d}{rlr@pC9FTuqbbkRQIeu{?F{aE~U`5HX$?B4x@IHs8vQUHN&1&Mi zO$F?0ZVRfxs-_^me8jk`=!;EXo7_rmC;0}eqc&1wg|0~O$rPj>e{=peZ@prjX_hXl zZUN*pF|z)7kekUZ-&@r7uc2Wfk<<5-%?;+f<(p3Pngx5G&b->KmZ_JVdwJjm^>g6` zvmO3(x6-L%5jy@wq9d;^9MOc*7QSVc3^ zN5qa#?RvJjrLH-{?=7};IKeXzUh^Q!tYj^@{I2wsksXOoe7$_-n>OqhmomBY|>5DqI&az&g2OT)T-oRIyjfFIgK+n*j`M@tb-gOrSnLh{U&Yqa#!qwG&ruf z`F%CYzs4N;Ie6ebYzo!jYKBd_j0<)nQbt>gNK3YS(YucwhL`~2SCJ9y?PWglq|!(8 zmVlYoqC?SCimtZ81gAbDT-%r9l~1jXuRu|fB$wt!#r@}}q^oc5kPH*H(VBCy)yFlK z%s0?=!ZunxC*BKg)SfrhEP*`==7@5dTcM4nLeYaXOdfdoXz6iDB3LxwFA6dY2i|n?$TYd*mae{1#IB3-4Hj>e~39 zSQs>>gjY$T-{7Me^Y_o310Ut=i=ocN(#a&-h4Ev^kk_gtn6*E3ZGWT{R=69(%3|zg zPBMpPDB~t!4el{EK9>3Pm>rdo-NBDpORAbt0!T8!MtxeuIqZ%FS|+_@_-5wvO#fti zn-Wsj+}c$)+|Y@wP=w1tg0s;SPs~_&tY{46u~c3+RakCU#Arw zW*);9O-8m8X$vFsvYh;VZwfzs8Gpa84oMEQ!_cn#wZhxhEBY*+vKo->c746gV@Cus zCWzAB&?Y{+W6n0C`@#wf1U0?Cwvwa0NQq!qxiFz&3WMZqS z#^SxqZf8bZKh0**um)(v{hXd$+bb|mMp}Eu$j8+8d0>pHc0gUMLqpM2VUdmV;&XKl zT}<{_HGayMOl;hMUTT;RYD$VLaQc>G=VhMm_9km-1Dd>`7@zk{Izp3OIJLCnIgwc6 z-R?3i7pXIB(I2TfyvT2keN9E)BMWaDx3|{TBgta6L5o8(A8mX+*jtAAp!<;* zQl$+^L9B`wV3##|BGE+Hp1DcUL1#)TN3uXO40kh#5Z7lgl zhE9~{N!kdp_4FBGPHXX!(}!Qn-A~kv`y}bfsC()K$mk?R1kaR*R|qO4X;pU5>C6Xq z&9~iX_^fHG!Jd>|4lk2hPcZNnE_W^T*HW384T&|J20+4B>x=YtXmu?%+c`tSiHfAz z94sQ$IB08w7VC>=+gVD8QoKcNad3%u1*2a1PHjd$B;iu^S(_!97Bb<>i}8vGwbHGn z`SX;x5?%2m>`elRSlSaaeBZ*h)t3G^Ld_*u;ksJda(7x@s8u|g3c-DQ!N{ei@tA51 zeeopgP77VzvRz^c>8lr|HG6Su;ljWq{Uk?8qvnX0@44MM9ya5C-)t@V@LH3!4EFs6 z{a@CVOgV<*i!JfjvN@in3lkJlN2&2lJ1G~v(77o*M=ex~9THt36F@9g&Jo0CPaMV4 zzKndf3s3ZMmlaGVEN8@P-XrIzCHIWu1H!GaMI|N2wAwjEEv8uKh^PV0*l?L3^@+vK zlFFO=RAn0$SlG&A_2RFof}O{Zy-)G?zmaN^Pd?^q@aSN1p)-nKRf1pN@Sj?DJ2d-C z(=)@U;b%cqmYD|D6Yl%Ep75G*)1mA#Z~qOYqz61lK%cE!nDs{ZLlRntZ5ypHX;_#nF%1vZ0qMt81T z$PEsfeW?^jN?Yn0uSm7|$ZsPyQgohFO}JxmTh?p|d9~;r7@6d}HX-Jr^OFE3LWb;r ze);t@SVm}1>3seXjVmLa%8UiuDP{7Qe6MO6EJF|w4BI0UVJ90Jl}ZG&F2+CwxrVPg`&XFt6V>69332xp52(B_kto@44i(m_tk4`$|GPYa-G z*9KlGlM>i7k1E5pzT~4~Bde7-TPC1`XgUQ-;cFz#STlEe2ew8EUAf0+TKn|N8;3MY zBVb-3F!MA96`OQu^Da6`8LSA?J`u+@e*M5+|K*57)I?cy;AkjADd`jzff%12+n2MR z@Xgk3c6hhmql>&5G0GaYm7C;_zrKvifcxRa<&M9*j8prW_OlOu%E8ZP;io?MsS|(B z3qR+^pX-CaT_cr9^Sw^Xb?sOhlqG7G-k;V#pS#w-fdRJxTU|lRGHXGOpYCPW*d{mn zL}A;jOXsReDs!!Z1H1A97Vel-RK+fX6MWgBc0Ku*T6B_UuTAFm?w-)PP~+LwNqK7R z^W1IY2w6A5x8W?5)ioHUE0f!OiSjV0UTIu>=0nNlI!Sb3R%XYA2yef;+VcxX^G6%o zL(8v8j?JFqq_174_U^c))5B+#+nf`ngMzz8kEKM3FoS91{Z{;egXElNPs#JoV$mLy zo7uhI^SzUAENqC!m<2S|{1->aZXKD9UCVjoDRG-~HMeP^Gat00r0z~$C|w*DVlB~y z8g-bM2kMtD6ir@!1fosZ<=YUj0#z}p5aTQ%U|OU50#V=yP#h> zQxVY*m~bb`5ru$X>Lr3ATG_h=;{V7 zFMt9Ih77DJNdeOvwf*M=_Pxmr%#KxZ>ToW$A(s*>akVNts&7k6$^?$2G@QgPFhAEU z?=9|;uqzJa6p@9yJ!sTS&K3S}fPtz}RDNHec0d?YmLPX)8`P)k+%NpXnBD<*3(L~Z zMsc%{EPFK5pK|kvN`b=zEk_*T+Z_|lWdGjj%CPz#xu7UP@!cUGqj!hi?<+W&U9D(0 zHv*nas72%z(55*8(Qz5|6Jqmp8d|D1$mPAMX2>y};!En2bI=O+JTiE4EPM7Q188dS zbp}-j{$?Y+MZW5sp6tq-$L{#3GAEd=49;9~uUizuJeEa$ z>{*u)DMV)ViD+0n?4S2;_d}~QMxJzO-dPA;xQI)eFCnR1=bCHOXJ-s64eF(hir+Vr zIc3)>9y+s9STqa39~F3^JFODf_=zDp&a)VJN|LXBQSxRB>lBroWEpC<=leUlSW<3n zgJK0QdHGxsY2gNU`xxk&r`@F)!dRb8O=h#0IleN~S6Ou)>{|L{;>l(F{?D?@Gd2Ak zPJM)ei73gi@c3!4XIWY1#M{cQjAT|gzEX!t%wa7lMC=y>-k5=$3_|-2-Ji)L^>)SO zq66u=SSL|Z%{37niI|I1){^dR5drE`NTm?VHfp3&l1`U*UT=3!D%#gaCrB})zh1g) zTWVrglFm{Wk|83y)VR@5>)Cv?VeocS_T+TM!&FW>YYUq7sZ>6lR!Y|aX_A}0A)7tV z?QS{W_sX5<^;)I-!c7V#d?Q*paK=zpIJk)3=E*=&a@UHJrq9Td5mJlUPn-%u8z*y| zA87gE2#tH)LN@mm;LLN2!eedyU!vgeE~>Nh?JNJ@paegIcJK11-WmFE;z>o3#aV6Z z*_tEWnn{(yx^G#u+rb6O6EkBjSN;?0((tCK73?Ob$2&?lIW}mULw8E60#rLtA z87G(#^*XwxlZ?r}!MIq~=TJL0%tH`fc`Q$e8L3ePJ|Q9DNq! zN?MLcmfaKsRD32>jfi^lwhJ(rikrCx4~+Eq_-q_doNJtBJ@ZLlxVWq+yXe{B(4tbg zj#F?cAhn>%Dc&b0VUkR)8*l6Oz)n3a-Qv@AiOD#1x>#I?b5*GFjxNVIpr)9nUI-rH?FcWgo=9 zdQPL(A#lBPWC+2veiTA{+2VWuD$I=!V6%kKOVbQj!*ErZ(znx`5G#*Dd23I$ zY{lIps-GL)I^jzihQ{2|H%i)iU2?;*L(LoQGqS43CS9Ui<1MPK1F5_EduRlpN$W+lX3o29HbeEc_keZgnkpv?<{IL%nal}7qAz=G z|BK;w4M|18g{)Ee7-I4JWCNLiIVxi?tKLjFN@vNEnZ>Cq;%bq4kFJKn#koV#&y&zm z##_~>)&z=Jqnod4Ft&l>k=b9}?`*<)i=vcZ)E7g@Aw-U|E7dz4%A#u~$Ft|31o?S& z%-VN{yv~s6)Ol4hHy~88_w}2egx5*_N$N>Uqt*kcKEgxw2>gevQ%?Cu=P3~Xf=D@`4OP?s;zQy^OB;S(PDj5V;uWq)L<#>r(n6yvVu0W^x zk_sE&-d7!0QHz-wuyTqz#UoMeax~ntj6N_>5o~=i1I61d8D3ya0$~TCn?WKm+ z_~gd}Qik!GpBEgKNw$6aIl(2Rx)fy)O;MwMOJx8HflU3KvQCiCh|v z$GRko-pVLq*Vy=m=CoNuFrLG&Rpv%+ z8T3BSPRH2r&-T^D{n2CCTv;?{9xw~Br|HS#(=zBq(IewUWYi0l1ah*^fub{7r$rl6 z(z6?w6>tl-^2F!m1tJl@{TY6=x5#3FQO+OcmcC@Z6+Zik@$9OJ6pFsQl&ng6tURe1 z*8(StkTmH}8;;q|Gn?y=Yzz*V73{Cxk-jl}d4#{e>v_{a^kcKzGQC;~eK|yU-HjSf zp*C3>9h2WqVR%fhvCV6W4^+_cE2KEj3-3$M4^$tVCv8Ob5^S#P?!pv~?#AM3+e@XA zPerEsGkPhcZgXv_uyPV3pAomO0v&G-1-fp=%_8Y`lny79vmQyFZC`QpSl9%)bU4Ot zl23X*W_@ypS6gBtptknu94f56o>&otUi9DU-AnIp37BXt-8=k3F-o8}-lFck=AgK# z#x6|p=kRmM3(<+S#rvAvKRSkysEv8FDNNP0R;i43k{IE!UqK(qcHreTdBb(#H8S!3 zGTuuWHL=pFg(C`f6}94B21#r;>fpkYrH*08aO$Dvvo>2S&tLJmozJdImo!V6b7hD& zDyQaiEuuG4%TFXw{_*wf=-&??E#WB9l(6#J9ZM=;Vu~`rA-% zs$HAt%&ys>wka`sda}?DFehr^GKByP#ZK;=rkq+OAS(B3_+?z9B7YIrS$q=Ey!Toz z02qr8hI$2*JJ)PP<@DrUUdEYyasdNm-{c?l&_0x_a>-8V6(|k8+X`SXfV2Cj{Jx!+ z1jr8Vebf_;J9i6!X8cgv@u@>7l>?V~u4t{f7a)V`SPPKdUB74kX~Gsopj;WgPr#aT z;wnIPXzjg#lco`yfO18E+L#FY=mTU=feb&Z`?Gg{3d7Gw?Wbn=sds-)6F(>6pKFGn zE3*H+3&^h=-g7(k4bFZes{x2?oHO_`{v=hEy?7M;UR?}7Yqx0mOz^uK)d-D+m5!*%~))_VM(GW#)j_dDC~1G74w=8q1DIQysQn$={h13CU6 uJ7mSf^Ltpwce3w2vKs#XM{q-Ncf9UxD From a2c8aaec67091ea16d3127cb465ea0906c19ccb3 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Fri, 16 Apr 2021 19:33:39 -0700 Subject: [PATCH 075/404] wip for fixing imports and generate styles --- .../symbols/pb_instancesym_gen.dart | 43 ++++++++++++++---- .../pb_file_structure_strategy.dart | 25 ++++++---- .../pb_visual_generation_service.dart | 2 +- lib/main.dart | 6 +-- test/assets/SymbolTest-simp.sketch | Bin 26490 -> 26493 bytes 5 files changed, 55 insertions(+), 21 deletions(-) diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 7d30d577..e50939f6 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; import 'package:parabeac_core/input/sketch/entities/style/text_style.dart'; @@ -8,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.d import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; import 'package:quick_log/quick_log.dart'; @@ -51,7 +53,11 @@ class PBSymbolInstanceGenerator extends PBGenerator { switch (param.type) { case PBSharedInstanceIntermediateNode: String siString = genSymbolInstance( - param.UUID, param.value, source.overrideValues); + param.UUID, + param.value, + source.overrideValues, + source.managerData + ); if (siString != '') { buffer.write('${param.name}: '); buffer.write(siString); @@ -83,12 +89,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { return ''; } - String genSymbolInstance(String overrideUUID, String UUID, - List overrideValues, - {int depth = 1}) { - if ((UUID == null) || (UUID == '')) { - return ''; - } + PBSharedMasterNode getMasterSymbol(String UUID) { var masterSymbol; var nodeFound = PBSymbolStorage().getAllSymbolById(UUID); @@ -102,13 +103,35 @@ class PBSymbolInstanceGenerator extends PBGenerator { // Try to find master by looking for the master's SYMBOL_ID masterSymbol = PBSymbolStorage().getSharedMasterNodeBySymbolID(UUID); } + + return masterSymbol; + + } + + String genSymbolInstance(String overrideUUID, String UUID, + List overrideValues, + PBGenerationViewData managerData, + {int depth = 1}) { + + if ((UUID == null) || (UUID == '')) { + return ''; + } + + var masterSymbol = getMasterSymbol(UUID); + // file could have override names that don't exist? That's really odd, but we have a file that does that. if (masterSymbol == null) { return ''; } - assert(masterSymbol != null, - 'Could not find master symbol with UUID: ${UUID}'); + // include import + Set path = PBGenCache().getPaths(masterSymbol.SYMBOL_ID); + if (path.isEmpty) { + log.warning("Can't find path for Master Symbol with UUID: ${UUID}"); + } else { + managerData.addImport(path.first); + } + var buffer = StringBuffer(); buffer.write('${masterSymbol.friendlyName}(constraints, '); for (var ovrValue in overrideValues) { @@ -120,7 +143,9 @@ class PBSymbolInstanceGenerator extends PBGenerator { case PBSharedInstanceIntermediateNode: buffer.write(genSymbolInstance( ovrValue.value, ovrUUID, overrideValues, + managerData, depth: depth + 1)); + break; case InheritedBitmap: var name = SN_UUIDtoVarName[ovrUUID + '_image']; diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart index c09cbfb7..d7561ff0 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart @@ -1,4 +1,6 @@ import 'dart:io'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; @@ -55,7 +57,7 @@ abstract class FileStructureStrategy { _viewDirectoryPath = '${GENERATED_PROJECT_PATH}${RELATIVE_VIEW_PATH}'; _pbProject.forest.forEach((dir) { if (dir.rootNode != null) { - addImportsInfo(dir); + addImportsInfo(dir, dir.rootNode); } }); Directory(_screenDirectoryPath).createSync(recursive: true); @@ -65,19 +67,26 @@ abstract class FileStructureStrategy { } ///Add the import information to correctly generate them in the corresponding files. - void addImportsInfo(PBIntermediateTree tree) { + void addImportsInfo(PBIntermediateTree tree, PBIntermediateNode node) { // Add to cache if node is scaffold or symbol master - var node = tree.rootNode; var name = node?.name?.snakeCase; + if (name != null) { var uuid = node is PBSharedMasterNode ? node.SYMBOL_ID : node.UUID; - var path = node is PBSharedMasterNode - ? '${_viewDirectoryPath}${tree.name.snakeCase}/${name}.dart' // Removed .g - : '${_screenDirectoryPath}${tree.name.snakeCase}/${name}.dart'; - PBGenCache().setPathToCache(uuid, path); + switch (node.runtimeType) { + case PBSharedMasterNode: + PBGenCache().setPathToCache(uuid, '${_viewDirectoryPath}${tree.name.snakeCase}/${name}.dart'); + break; + case InheritedScaffold: + PBGenCache().setPathToCache(uuid, '${_screenDirectoryPath}${tree.name.snakeCase}/${name}.dart'); + break; + } } else { logger.warning( - 'The following intermediateNode was missing a name: ${tree.toString()}'); + 'The following intermediateNode was missing a name: ${node.toString()}'); + } + if (node.child != null) { + addImportsInfo(tree, node.child); } } diff --git a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart index 3cf24849..375a5607 100644 --- a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart @@ -95,7 +95,7 @@ class PBVisualGenerationService implements PBGenerationService { smHelper.interpretStateManagementNode(result); } else { smHelper.interpretStateManagementNode(result); - continue; + //continue; } } diff --git a/lib/main.dart b/lib/main.dart index 09aa2aa6..b8bbe0f9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -59,8 +59,8 @@ void main(List args) async { help: 'Displays this help information.', abbr: 'h', negatable: false) ..addFlag('export-pbdl', help: 'This flag outputs Parabeac Design Logic (PBDL) in JSON format.') - ..addFlag('include-styles', - help: 'If this flag is set, it will output styles document'); + ..addFlag('exclude-styles', + help: 'If this flag is set, it will exclude output styles document'); //error handler using logger package void handleError(String msg) { @@ -95,7 +95,7 @@ ${parser.usage} MainInfo().figmaProjectID = argResults['fig']; var designType = 'sketch'; - MainInfo().exportStyles = argResults['include-styles']; + MainInfo().exportStyles = !argResults['exclude-styles']; var jsonOnly = argResults['export-pbdl']; var configurationPath = argResults['config-path']; diff --git a/test/assets/SymbolTest-simp.sketch b/test/assets/SymbolTest-simp.sketch index f4e0a330a854a711ef4d141d5b6f6e9fb94b2258..5e3cbde60e11292502bc9b9d92eb07db273056af 100644 GIT binary patch delta 5038 zcmV;f6H)B?&H??-0kCfi1SGohUXybRQ-85{_TkJ{ijioG8<|v5)Fhsi|NCi>)XjD> zieovphk0-$00bI9ynm{j z(aW=Jw#eI@SuvmIlb@@)__HdTY<4s6x4dqO@lMV!)%Zg`*-H4WSQPJP`RHX+FCk%; zUFP*K#iB_+&9ia>ZC}nI6CaJr>;gWF7MBXqi{j6sJa<*OXzHve zL14)?>Fdhss_DB4Ul!A9Ih)uz&woC=&K4is6dqhlxLoA*tMaTGz5F~HR~N@wSzKh< ze15!W#%S>&Z^lzJpDoYhBiBl_AAW^NX(xgQL1n-e38NFliRCC!gd=ZclIYa2MDWqo z)zK*b6i52aJj%C-m98gvHwQ+q9M6_8M!&>Cdo_U~|M#DM2-lCV`*&Iw7gXzBbv1>m zzQ~&PF=+R!Zbx{ly&9AVni;P~^VhnHk98IIHBIy4eA=|_d@Lr-wEgs{{d)<2q26&+ z1{nM}wyHv!XZ;kMG()h(LK*{%>>%5{^M4IO{Z>JNFnp81QSi3$e)jb4&CI89bJ z*UEe>$_WVeb{R#1W$=EstaoH;6QcH}Wd_Q-(dThqLiJGMGd>naFW}D=l)I?nm?h=; ztk=G5QY;sJ`&qMGEjeha>14QyE3%$!&Et0KJ2^XIbjx6pEvCO_4M4T&1kr>vd>c&8iw!QB%jYw%zz{&TV7xzK$AE=8I1I#<6U+Xxi>gmtFfi zy}s%S<)509ylG(IcUwHKv-z|bFWj{?%AfX0yI8MOo(c$uyf( zAN!QW=F8Pe6~`Y=r**YFpRNY+9KOwAWmSL6W=EXYC$BCpmQCz)sPp^`*3dt;ieB{# zFxI}U#Vu@ssz>#>uFN=*IPuD(G)*z$N)x1mV}K9VGwy_So<4qzrfZD0%ciNy-+%J? zS+<-thsWx!#-|CKRIZWJ$QC*YHtewI$!(%>NK)id1L)}-M>>%lQ6nW$j1yt_fS!K? zdL9%#fmP*oolmyW^JtWPD!QJ}+LWXmPpi7^{YCcar1*2Chh_iy3wRq>VAiV4b=?nX zqP+mMw}gZ4a{+`nSc`C~f?y#K>&fE>Te1e*x2vAMAnZEQ_LbfSwM2gxEq*Roi|8>? z#wgAS2XlzY9FY!u5jz%wD#E1F8e@Nf31o?b@mb|S4lvUUPYF-}fU|L`kl&jPRG|Wt%0i z(U=)Zgw&F%xacNr1{4%}{h&SsjGxDe$;;+?OpSVu3|d&99B{>X{SBf)ev;QLI5_|6wKTQ6&AK5wMQ;X@-2$>}@7%H8)pR z5ovbnYhdg@bel2&2BBBaX_w!sCnnu0@ZHx2C_UdS0=2z1wigYoh0WU7c|@9FZ9KBI zQC7tQ_}e7!4tn~pOmH11eHJPBN(#x28PI|<&nFS4{>WQ`dRqN6|M<3AmJ`>?yx3`?D;AB78>OP= z?+if1y_;6PPXY_hAf`9p(Vo(D?w0nh$h zV_+7|kJ$Nq@xS?HOfG*G$+D^b-JgwLJ>3(2Vy+uc-5EdoW}9f5!DiC(^j1$(Djir} z6s3v;1ZJ2;+ERfy<&FoY9OG)VzbO?M2{bVnDMmHop3|uI21%Y6ohWLtO9oSFIN#di zeCwzM){`5Gw@Hn9G=?@NNz>HD`(=~2;=Mjue+NacL81Witg8= zwo_G)ey}nx<_&rcY-o8AS3`UJMd-0qG-Ap;tFv}2Zc2MCEAqS}P5CdN2KDR`o&pS;u3=>Y!+CO9j;D21f-&;%qM4qwF1K}w z^V#KmY9oz`UHJT&@uL^w>gdI1s(`bBK8-ryJBdJ1o^OBI60C!PZR;WuJlNiBHvSM# zx+67fjj9e|`(685?yEBW)G?`@Qm;y|XO@$H&1Y4%#^^|-s*gWcQ3+NQ6NpUS_+lIf zGpi%Fxa!$W-l1Q)uKN9Tx%M*E$(Ah+wmI7})nQt=!Nf=mWSSAaHq{AXYCA7_1lGJT z?vl07nrwfUbF5RNpo`wlTo#jj#Zy-6{jSe<>i7n#sk_v#Ps=MHKUq2640Y$M?KrgZ zL@*#DN+ksGM5QPRSRqjjq|MZ)?N;b`fRE?eS)}=w+l|z`py`m8`1@|JmWd zK2-i)2V1{oaXNRbg9mASvnR%-yRYk85iPh*1M+`5Rfs#)lC^+H5EKjV6_)8!^2V%O z-*3vF;~);M?>oA_6+e`xC9zT~EKw2$jetTmz8`0$CL> zA}N32flA7J;NNh_gOyFZ!ycthc&IKBpvk~cgrP1_kJGf(IR?Yd8Xo;)Fji^O$VPmc@WEd`_{)E^zg#%)v6T!_ zMnO+0wkU~V>?Wi(VM215_-`m% ze80$iHQy$??YExa!smg~{%tAk;|s!go1ZUdS^bowFz(IJ+;ZVlMFgkXP%b1E?V7zM za)W$VcN6HzN{^eYbGB!;Nyn296aKKg0aD4#0M~i7laHEA49~)EfH29 zsZ2t`i9=psjkwhkY3vvxsnfw&nG$OsBI08YWAuO#AN#a^w}=m8(;z{0kWmRnoO_Ba zcMc`k_ka!Hu#@{0BY%6>YD>G}DQBEp6D%@- ztcYU*`+c_mx>_(Hj7ehR0u9{sq;_qmPCJm_>MjR zoqIMHC64jdKgv2gT1D^YA?;}Cpb6nsJg2d74Ol=bEq@TEK@jDXR0a?1ZeVwh<%O$X zz69ZvN?k%QY_c418asisA_O_f09{Q0G&REu0RJv#@qyn{9lWJNr6w9B0deEw8~%(( zj5+I4FOwkEa8F^lr!WMr4EGdn-m>S;oH@xd_c-P_-OthuRfUpC?-gD6RolXpo>!659F|xt~t8f6oCIK!RtRaCYuY{GuWt!(7HN?8Gp@YGy4yiGbt|p2B zaiy@^+XVgyYL!lC2$gxXiP)h>@6aWGM2mk;8008ejanfs(fEh>zK!DU60g{u>8AN{xG$yH=1R*9! zcwvZ0l!YkbS%d_mzDxatdMtoRw^~<9*6$nDN>l3Exj^2zQ+8STsETX-sZs(7p0@)unjSv~Ljq*_zvvz~W4zgNXk!>6(*~U0tirIAh!8h;g?-tGe=+vR(>ZccztP4VWoDwC~qz zwV6DHKix|ARl!>&@2_NcFIF&d4^ll^*WWjGG{pJo5b=2rxKrm<51`*!FD?rh^7qe^ zPy6Y6Yu9bLKCzMMb}h{?ZF}zAwS&t?_FBj)n8|m(eQ33vHZDm#t+Z0*a%BcP4`pFi z!>`BTa|55SZf>&!p|GA_>0%7WN_OI?eZO31Hq{)&*mBA<7YA8JM1(L)DIytHZ zv4ntdf>@%6FouW_F^DQ0-dXr6oUg+9TZD7+I zCy4Sy;7r(?HV2bn9U6ZnVaB{DbrBB|kXV5|6va?7z<{aJ)j%o5lm znFqv6qtFZE7x6|0B1v3MG4inwj{2^Z^dLo1mhu<}l+ZZ&UU*;5{!}L1?Cd(*&og{x ztRGHlC7uu>0`M^9Dcm)q5bSv=@`dmL3gaw{f0Mo*9aSC)hngwEL&ZegZ}wUjx;)A_ z7r=in2I8ewXX6A}84`pfNsM1Fov$U+e=M2Kor8K`oT%MS(^Z{=jUqOno437D1H7xn z{(rF;1T_PE`?lF)chHlQFdroW!jo1X9)Gwhm-QOR{1>$ug4@Ve4vBaks*^5jvx4X* z>Q45Rxwd3b^$?%-y6x-yAck^h1#Vk_0=8g1R+w+FM?=?jJwFJ;z_k#+oFcQV-5!N< zipdPxvrfC;$5Agzy*bIv?A2hHc!)M^B7NiwP;oh28@I!{j? zK0hPd^Rp)pQhkPjgwCj^(*=pEmHbj_dt%@*UPmq7_VaM|ahc!SN3FUTGP4uz=~zGM zy{yy6u{@fMx~xT|`{L)O(sD2TwtqU(4{x>Q$>cx-6^SxQncHZ}c5_6e^218k>dc;$ z`tA=pvX8dLQE;@Hd^P03JG?xzU^^8-YLx7H5B&Dj z>t8`b$S`%88{jY^kEI5<*J|_gCz*h|-Cu(19Zsxqjf{kcEC2%{6Yu_FQih zY2>`**|%Dt-FT)fd#HqWWztT9e%t)*=YOBMug8Z%kN%es;YN$+DE|deO9KRxx@H=) zKq1OR1SGohUXu=HSq1Msanfs(Y-Vx+C6nJ~HUZ(27H2jBC?%6YB^HxpXAlO$WdHyG E0IBo8c>n+a delta 5057 zcmV;y6F%(y&H?()0kCfi1lLO^NRx95Q-5)G_TkJ{ijioG8<|v5)Fhsi|NCi>)YVQ# zaV*EqFb|FdfIt&yeE1sOfIf}hj%V3oF?v3lXBYYCWHhPXR`33skDC`B5}A_;^IRdT zjYpi)6xq~y#3VJCGb&Q0;h}d`HOsT|)jY4Wrl`u%b3{%?#Ud0R^U0g)w<7;AuYc-h z^!z-VE%G*JR?O%58NOGuby zS9$$Qv1rnd^Q@de+gEeQ#3!RNyMzy;#nt7zYPJ}42`@SUS5MdZqWH5YFI-hFnmQ{= z5LmKJ`ns~ZYWmlNFNIrRxFS&4J!4$Fn8$(J!&nUQD3K|NW=$!u8|p_j^+pmsIPw>S_vA zeVH}wW6i2oQ9{J0ni3$e)jh>U(IZakK zdu2WppQdsHx*z+irX}=e9n0S4WK~^F^n9<5)IZH0|q6mtFfi zZ++br%0D(|dDB40@3weRXY*+>Ubww7aa`i~u2ia;XXB!|>MA@hX0!fXin7e>vuQS| zKJ+Pz&6n$yDvsa3nby_vV!G0VD(lo`0D@~9NjsZSc&$tuTdHVPBU|Vs*s$ZGC%1{lAxV)-4WOrU9O*=IM2(b0F;0Zx1A2cB z=y_E11Xh*Tbw1ff&y!L1vFP4>)}|!ocv{u%+h1lM&x$`+dRX?KKZCb%24=0w?CX9= z6YT}4y(JuUp9>(w!CHh<6$A@`SWg~5*pfBazFxiQGs5W8qV(DHGIiLX_kR%LspYUba~R z8;zNvL`W^Eij!{AWjxNU~yX4PVY z+H=7C=5@OQ*?gM)QB=#0FSZ$b-9KK|f8@W$jFvLg(DLim;>Ayu<|kc|uo~=ssN2L& zkx2jTO|@MhuK$|{SG1!~j79sTR;bN`JA?MM!jZocj@(r^axcP>zY>3r+*LU8jl$u- z5)R*0xbDHI*5{FeucVOdlmRU$^L!Fv>W{o7sBfx&<{w^H%W~pcnHM`vbj6~vaidh! z{GASnxOdaa_eo&E8N{?n!O}@BvY1-rjJ4iLnWmK8YU$udx%1!cD!u96^uP@z`ha`? ztuZi*=0|+_eDS~eRZM>_7Rj=y{@w45Uq9U)eq#2Gr*4m*eYH(A&0sNUd3vj-DU}W^ zFN#t{0s=G4B5kQaoN~tlQ;u;pI^2{Bj0Bn(j1;39anET~dxIoTj7}7_*d>E0HSBL4 zu)lTE0_)ig#oMGtJsLwBlcZ_t;@z^zTk&3=t-ph!*C0^<`PP4FJC&V7j?Wk4x|lZ| z4cn=zM?aXEm-7a_1U9t1jI*KL{vz~LDjG3mp4C~~7dNHd%Zfa21~1s}&cBJ{k(aHA z^_zNGjyLF-&5DcivSrB>+PL{vE{^x@uk|(D^<)HdEQ%1>KO<6Oj0pvkK;W49N57gR z8*y-a=WI`!o%VlkWX1{Il^XSn$aY8XIBVK+o7aLFQEm0gtTzhy{!l&qs2_1e9zvnM zFzT(Hk-^Fd>sK86*_E%e53kC90X3*+SMU^I*mMmm6X?#ft8zT8s}hWne;3X4taZ7q zOI*yZ=2IJKRD6X`pBO)RCazDOeWD6D8|c%h1HQ8e6y<-#mMy_L7}&NhBEf^@&1U2G zai=>{v(~8U5Vl{n_i|s9>Bo*q?UZ^^f<3dG{A)g|vNc9WB2|6(xr$1#qL@Hr^2QhA z*qK=!xy5zQZt@QO%5~N6_T@UrR3}@uIN0WF%T$M9;RX{UF_39S_}Ww_gsJVk=n+`+ z!njJ-K5KunUCyyije;(EJ9Ak~@)b{6&G)-L->Ks(sHW~xzdS52fc#|Tc+=ILv$o^V z$`iqWj3|{5#1oaGBw&q<7LsX5<21TvtG=xb``bm7Ew{(3-J(~KegXULQ&+OCD*R`M z1BX!gw;gQ#mc`-Ru?`-j_05_Xr|zMyZ$-4=It_ow>r^4`R7=(ZB0*3ryjNJJPstmz za(%xle~z6vxW4b``d0i{o|eQ)t+)j34TK{eFh_=_U@bVx6d_m>8wTI^U>p31zHdT} zOl3+?nplgt#0(h)p8{75>%?%EvZsW$8=iAG&<>98hjD!GZSpAYh$B=Yn{W+8DhOm% zz=(gOga;}q^MQZGCJ$CN@eX^GI^m(ZM1Up(LlK6$Ks`>=R+EQKp21%}_yh-k`QR@f z=EmSJAN=KmzkKkQf8JkCh}VG&B(32HFqQ*Zb--AqNh2HaX~GA8`QR`A-u`moyvJ5D zL>UD=rP!h*hOwKF+Jp(oW#YfWluC_b)DeG;B-RSlUOEK2Zjd!`r<)2VQ++?C6dwHL z1M~eX^VNKt?6%)}ehZ%mO8d8^w2vj>5P%Lvzc8PZbfIYD2k@ShREY zmdFkAO_3WLzuGqjZ>R?g-uS$>Jg$*^;DC=C+H&-W4+_Qxj}afh6rK?>M0^YpAGcRT ze55i72`3JDfi>b*OQf-5h@?&jV`WOLeTayU1B}rlMtmI7`rRTvj7@_C)j>uj7;)|? zvfMe8V2@K0Lx5FydJ!M=>+I~mWweLh+z~@~AMXJRz;ToM6(fIZ*J??-;VEaFTN5lY zfUJmP0_&NT0f|Jy91uR}K%U;^GGB4i!8cw2_M-%RP~HM<=Q%%0U>!+}G}a;JVuVL( z1OgQU;((pA${EJwfV2bB9)z@OOzCa2PQrf2=q>@;D+6P@z7^+f`STvA?&OWWH6j|? zZ|ga5?;hy%U~PZ?h}LFTZcBTG!%4~|V5SxZaTW~H)M%87#3wXpq1z+6$2K+(;RtWn zV&AK!c}Ua0|MY#&Kis2?ce9ygDzr3-LY{yT&ZS}qfX$*58x?{}T#~c2P zM~pe^QZJJr)o@N>IHxcKt_IjWlS**TD5GS3HvF;O^=GLkK?;I+8ZYxu zHo#QS0tt(KVlefbgu%QTHl~KV{)W5$hP(cTyZ(NtyZ%-vJ2>O-DfHVXjwY!~kRvul zT*sfqayE%S66A33K_sn@>)77-L-_sioZSbtem8$NcEIpBPBmhw2lA&pLr|MROc|0m zEj%~$>AA66XA~Pe*k3j>qOHCP{uZKhS_?{#9Q>UyW|fG?IIsd;b{c7&QsgPoR&h>2 z4+p39U>n@UX}zKvNBEi0&&F~y%ncx@N0vmJmoS2~0TkuRd7OeBEh%}zKNR{PaX>$g z|N4KnKp=*9QVD4RR+yuO1^JYuF=8<|>k&{x9DlWzqChMtWuh%j2810D_MU^j4W~@}>1v`F z5LXJTy-nbcpjPRGhJd*pV0D1i;VjJ)K1*mb?BCt*VHzd4RGbOqbaVy+5kQ6mE0v%| zpkUkt{SY@d9KsQfbeQIlroZ=LntPOSYZvl9B|OB+KGFal()8~?ecuh@dz5i!8~Hz9 zhS~3pRM-CxP)h>@6aWGM2mk;8000rEocL&yfEh>zNPyHE0g#i<8AN{q8b#`gFv0=i zUKF7q&LR}EEJmCX-zB~v9t~mAt=5&2_4`J((v-S(E|7QblwDRns^VIID%C@yTjN~Z z$*NOBPgORJD&Fe0{6*JBR?quBsn(SFtmmE1?^SWs@Tu&|+e$eXrtP7jk{i{&D?5`u zHnJ|j_NIYO_uQ%F8h(E`i_Q90SJ$dD&e(Q2V%#mzs;>N{te0HZooQuR17?B`?fdmw zZ6;6QPq)&2Rj^jc`zzVq^A$|ogH(^!_4kb(4RL-tM10-@?$mkJ1L$|wi^~Fr{QdLf z(|-Ei+I3s5Pi$nmT}v}e+nzgj?cnl}y%w?xX7ZhHA6jjvjSERnE3H(yT$#bnLs^*B z@au8-+`uQSo7?O_D6FSfx){T;k{v&4-!IphO*IEGww&_J#bK5OJVuzN1O*w3foCyC zNyuH11(65?lUW-)420)r@Uew)Yi(ne)RUnbEdgAU&l^MmCy3t-SF%AaJq?it>iJ;+I31{q6LNn$g zDgqEr5K9yXl%jz11Vj}M?<{&1&R605Ey6kZ@%t)gHwellY$;ji&-qM19}~(zIw=WJ zz&wf)?lF`?fshh6WkZDiQ2NPwV|49bL&8o4bXxNz1r5SKV9AMHvX@Zb_XY_K3CM@l zQ1ZGVnUnWU9UQa_~TNdh*ta^2#uCqSpF!ryb8i^>QUYxp!g#sj&V-Lj%lnij+ z@-mMK8ZvUTM+xSKWiFhQBv}%89Es3{c`PC*aydp`%A+i1B=r~r!T)`M{NqoaACnXo zM`^+s3V(=;QB2`i7EtU)NgVJL-wa~4n6~x~FwdALEZ{gvp%`*WhN3j!$Rn|bIed!5 z{|0~q&x3(M2x*KVtJDn;OE^J{#A!$(BGM$d0VRY~?(FOkzn|=#y|3R|+usY_urW@e znfiodOnj75FN0_X3`NX`kryQ|;tjbFE+ZKE*at^_*GhVrqBu)gf==!9)F}N zm-QOR{1>$ug4@Ve4vBaks*^5jvx4Xfbtn7ETw5}zdWcVZ-S%~U5JS1M0=F$d0b8&h zE6g|8Ba!R6o*zb0=vs(hPLWyGZjVAa#bgHUS*P9a4L=6N`5J|Ju&bY zucH=k`*}F~n9T3(qgGuEnb`^VbgZBBUe@X3SRTzrUDmwPeerWsX}OnvTYnwthqv1D zWOAT^ibNSv<~EwL-5e3A{IJrsI`d82pGE7|RhB%6Y*ry>TdtO3U5J5`>_gC!G zn2?F6(1BwbyME~6h(>-C&oyqw_FQj;G;&_@>{~6+Zah<#JygQGGHEA4zis~Z^S{sB z*W*KxNB&EQaHGX@l>Y)yO9KRxy=EG-Lm|pU1lLO^NRts}Sp^ZNocL&yZ)S1 Date: Fri, 14 May 2021 20:05:53 -0600 Subject: [PATCH 076/404] Extendes input formatter Co-authored-by: Ivan --- lib/generation/generators/util/pb_input_formatter.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/generation/generators/util/pb_input_formatter.dart b/lib/generation/generators/util/pb_input_formatter.dart index f581bd00..75a35733 100644 --- a/lib/generation/generators/util/pb_input_formatter.dart +++ b/lib/generation/generators/util/pb_input_formatter.dart @@ -15,7 +15,9 @@ class PBInputFormatter { spaceToUnderscore: spaceToUnderscore, destroyDigits: destroyDigits); (isTitle) - ? result = result.replaceRange(0, 1, result[0].toUpperCase()) + ? result = result.camelCase + .replaceAll('_', '') + .replaceRange(0, 1, result[0].toUpperCase()) : result = result.toLowerCase(); return result; } From c808549c3c30c8d2e5c431a4bcbc06ef26530f9d Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 14 May 2021 20:06:25 -0600 Subject: [PATCH 077/404] Changed orientation generation Co-authored-by: Ivan --- .../pb_generation_configuration.dart | 3 +- ...platform_orientation_generation_mixin.dart | 60 ++++++------------- .../helpers/pb_intermediate_node_tree.dart | 10 +++- ...b_platform_orientation_linker_service.dart | 5 +- 4 files changed, 33 insertions(+), 45 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 08ffcbd5..ec6c9486 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -138,11 +138,12 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { _commitImports(tree.rootNode, tree.name.snakeCase, fileName); if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { + getPlatformOrientationName(tree.rootNode); tree.rootNode.currentContext.project.genProjectData.commandQueue .add(ExportPlatformCommand( tree.rootNode.currentContext.treeRoot.data.platform, '$fileName', - '$fileName${getPlatformOrientationName(tree.rootNode)}.dart', + '${tree.rootNode.name.snakeCase}.dart', await _generationManager.generate(tree.rootNode), )); } else if (tree.rootNode is InheritedScaffold) { diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index a87a35c8..f1aa7479 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -9,9 +9,6 @@ mixin PBPlatformOrientationGeneration { String screenName, PBProject mainTree) { platformsMap.forEach((platform, screens) { var formatedName = screenName.snakeCase.toLowerCase(); - if (screens.length > 1) { - _generateOrientationInstance(screenName, mainTree); - } if (platformsMap.length > 1) { mainTree.genProjectData.commandQueue.add(WriteScreenCommand( formatedName + '_platform_builder.dart', @@ -22,18 +19,10 @@ mixin PBPlatformOrientationGeneration { }); } - void _generateOrientationInstance(String screenName, PBProject mainTree) { - var formatedName = screenName.snakeCase.toLowerCase(); - mainTree.genProjectData.commandQueue.add(WriteScreenCommand( - formatedName + '_orientation_builder.dart', - formatedName, - _getOrientationInstance(screenName), - )); - } - String _getPlatformInstance( Map> platformsMap, String screenName) { var className = screenName.pascalCase; + // TODO: add dynamic imports return ''' import 'package:flutter/material.dart'; import '../../widgets/responsive_layout_builder.dart'; @@ -53,45 +42,34 @@ mixin PBPlatformOrientationGeneration { Map> platformsMap, String className) { var result = ''; platformsMap.forEach((platform, value) { - result += '${platform}Widget: ${className}_${platform}(),'; + var nameWithPlatform = className + platform.titleCase; + if (value.length > 1) { + result += ''' + ${platform}Widget: ResponsiveOrientationBuilder( + verticalPage: ${nameWithPlatform}Vertical(), + horizontalPage: ${nameWithPlatform}Horizontal(), + ), + '''; + } else { + result += '${platform}Widget: ${nameWithPlatform}(),'; + } }); return result; } - String _getOrientationInstance(String screenName) { - var className = screenName.pascalCase; - return ''' - import 'package:flutter/material.dart'; - import '../../widgets/responsive_orientation_builder.dart'; - - class ${className}OrientationBuilder extends StatelessWidget { - @override - Widget build(BuildContext context) { - return ResponsiveOrientationBuilder( - verticalPage: ${className}Vertical(), - horizontalPage: ${className}Horizontal(), - ); - } - } - '''; - } - - String getPlatformOrientationName(PBIntermediateNode node) { - var result = ''; + void getPlatformOrientationName(PBIntermediateNode node) { var map = PBPlatformOrientationLinkerService() .getPlatformOrientationData(node.name); - // if (map.length > 1) { - // var platform = PBPlatformOrientationLinkerService() - // .stripPlatform(node.currentContext.treeRoot.data.platform); - // result += '_$platform'; - // } + if (map.length > 1) { + var platform = PBPlatformOrientationLinkerService() + .stripPlatform(node.currentContext.treeRoot.data.platform); + node.name += '_$platform'; + } if (map[node.currentContext.treeRoot.data.platform].length > 1) { var orientation = PBPlatformOrientationLinkerService() .stripOrientation(node.currentContext.treeRoot.data.orientation); - result += '_$orientation'; + node.name += '_$orientation'; } - - return result; } } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 4079f099..c757a56a 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -9,8 +9,16 @@ enum TREE_TYPE { class PBIntermediateTree { PBGenerationViewData data; - PBIntermediateNode rootNode; + PBIntermediateNode _rootNode; + set rootNode(PBIntermediateNode rootNode) { + _rootNode = rootNode; + identifier = rootNode?.name ?? name; + } + + PBIntermediateNode get rootNode => _rootNode; + String name; + String identifier; PBIntermediateTree(this.name); TREE_TYPE tree_type = TREE_TYPE.SCREEN; } diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 4a3bb12b..f16ef7eb 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -55,7 +55,7 @@ class PBPlatformOrientationLinkerService { /// Adds [tree] to the storage void addToMap(PBIntermediateTree tree) { - var key = tree.rootNode.name; + var key = tree.identifier; if (_map.containsKey(key)) { // Check if we have exact trees (same orientation and platform) var trees = _map[key]; @@ -205,7 +205,8 @@ class PBPlatformOrientationLinkerService { void _addBreakpoints(PBIntermediateTree tree) { if (MainInfo().configurations.containsKey('breakpoints')) { - Map bp = MainInfo().configurations['breakpoints'].cast(); + Map bp = + MainInfo().configurations['breakpoints'].cast(); bp.forEach((key, value) { var cmd = AddConstantCommand(key, 'num', value.toString()); tree.rootNode.currentContext.project.genProjectData.commandQueue From f615c9f839579decec3cd9b35565f9464ba698f6 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Sat, 15 May 2021 00:35:27 -0600 Subject: [PATCH 078/404] WIP having the FileStructureStrategy notify the observers of the file creation, like the import helper. Moved the method that write into the files back into the FileStructureStrategy so it can notify all of its observers when a new file was created. Finally, adapted all of the FileCommands based on the method move. --- .../file_writer_observer.dart | 5 ++ .../commands/add_constant_command.dart | 22 ++++-- .../commands/add_dependency_command.dart | 43 ++++++++---- .../commands/export_platform_command.dart | 21 ++---- .../commands/file_structure_command.dart | 21 ------ .../commands/orientation_builder_command.dart | 12 ++-- .../responsive_layout_builder_command.dart | 16 ++--- .../commands/write_screen_command.dart | 7 +- .../commands/write_symbol_command.dart | 7 +- .../pb_file_structure_strategy.dart | 70 +++++++++++++++++++ .../helpers/pb_configuration.g.dart | 4 +- .../helpers/pb_project.dart | 1 + .../commands/add_dependency_command_test.dart | 21 +++++- .../output_services/project_builder_test.dart | 2 + 14 files changed, 173 insertions(+), 79 deletions(-) diff --git a/lib/generation/flutter_project_builder/file_writer_observer.dart b/lib/generation/flutter_project_builder/file_writer_observer.dart index 46b3d1a3..51ec1afd 100644 --- a/lib/generation/flutter_project_builder/file_writer_observer.dart +++ b/lib/generation/flutter_project_builder/file_writer_observer.dart @@ -1,3 +1,8 @@ abstract class FileWriterObserver { + ///Event receiver that a file was created. In the event, + ///there is going to be access to the following parameters: + /// + ///`filePath`: the path of where the file was created at. + ///`fileUUID`: the unique identifier of the file. void fileCreated(String filePath, String fileUUID); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index c1b7e11a..acefeff6 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -1,3 +1,6 @@ +import 'dart:ffi'; +import 'package:path/path.dart' as p; + import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -6,15 +9,26 @@ class AddConstantCommand extends FileStructureCommand { String name; String type; String value; - final String CONST_PATH = 'lib/constants/constants.dart'; + final String CONST_DIR_PATH = 'lib/constants/'; + final String CONST_FILE_NAME = 'constants.dart'; AddConstantCommand(this.name, this.type, this.value); /// Adds a constant containing `type`, `name` and `value` to `constants.dart` file @override Future write(FileStructureStrategy strategy) { - var constantStr = 'const $type $name = $value;'; - var path = '${strategy.GENERATED_PROJECT_PATH}${CONST_PATH}'; - appendDataToFile(constantStr, path); + strategy.appendDataToFile( + _addConstant, + p.join(strategy.GENERATED_PROJECT_PATH, CONST_DIR_PATH), + CONST_FILE_NAME, + ); + } + + List _addConstant(List lines) { + var constStr = 'const $type $name = $value;'; + if (!lines.contains(constStr)) { + lines.add(constStr); + } + return lines; } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart index ee600046..c97f25d8 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -5,7 +5,15 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure /// Command used to add a dependency to `pubspec.yaml` class AddDependencyCommand extends FileStructureCommand { + final _PUBSPEC_YAML_NAME = 'pubspec.yaml'; + + ///assets yaml decleration + final String _ASSET_DECLERATION = ' assets:\n - assets/images/'; + + /// Name of the [package] String package; + + /// The version of [package] String version; AddDependencyCommand(this.package, this.version); @@ -13,26 +21,31 @@ class AddDependencyCommand extends FileStructureCommand { /// Appends `package` and `version` to `pubspec.yaml` dependencies. @override Future write(FileStructureStrategy strategy) async { - var yamlAbsPath = '${strategy.GENERATED_PROJECT_PATH}/pubspec.yaml'; - - var readYaml = File(yamlAbsPath).readAsLinesSync(); + strategy.appendDataToFile( + _addPackage, + strategy.GENERATED_PROJECT_PATH, + _PUBSPEC_YAML_NAME, + createFileIfNotFound: false, + ); + } - // Ensure dependency has not already been added - if (readYaml.contains('$package: $version')) { - return; + List _addPackage(List lines) { + ///Appending the [package] in the [PUBSPEC_YAML_NAME] file. + var depIndex = lines.indexOf('dependencies:') + 1; + if (depIndex >= 0) { + lines.insert(depIndex, '$package: $version'); } - var line = readYaml.indexOf('dependencies:'); - readYaml.insert(++line, '$package: $version'); - + ///Appending the images path into the [PUBSPEC_YAML_NAME] file. // TODO: we may want to move this to a separate Command to ensure it only gets called once. - line = readYaml.indexOf('flutter:'); - if (line > 0) { - if (!readYaml.contains(' assets:')) { - readYaml.insert(++line, ' assets:\n - assets/images/'); + var assetIndex = lines.indexOf(' assets:') + 1; + if (!lines.contains(_ASSET_DECLERATION) && assetIndex >= 0) { + if (assetIndex == lines.length) { + lines.add(_ASSET_DECLERATION); + } else { + lines.insert(assetIndex, _ASSET_DECLERATION); } } - - writeDataToFile(readYaml.toString(), yamlAbsPath); + return lines; } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index be664a1f..feb2dafb 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -1,3 +1,4 @@ +import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; @@ -17,19 +18,11 @@ class ExportPlatformCommand extends NodeFileStructureCommand { @override Future write(FileStructureStrategy strategy) async { - var path = '${strategy.GENERATED_PROJECT_PATH}'; - - switch (platform) { - case PLATFORM.DESKTOP: - path += 'lib/screens/$folderName/desktop/$fileName'; - break; - case PLATFORM.MOBILE: - path += 'lib/screens/$folderName/mobile/$fileName'; - break; - case PLATFORM.TABLET: - path += 'lib/screens/$folderName/tablet/$fileName'; - break; - } - super.writeDataToFile(code, path); + var path = p.join( + strategy.GENERATED_PROJECT_PATH, + 'lib/screens/$folderName/', + platform.toString().toLowerCase(), + ); + strategy.writeDataToFile(code, path, fileName); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart index f3b493b8..df421e60 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart @@ -5,25 +5,4 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure abstract class FileStructureCommand { /// Method that executes the [FileStructureCommand]'s action. Future write(FileStructureStrategy strategy); - - /// Writes `data` to file at `fileAbsPath`. - /// - /// [fileAbsPath] should be the absolute path of the file - void writeDataToFile(String data, String fileAbsPath) { - File(fileAbsPath).createSync(recursive: true); - var writer = File(fileAbsPath); - writer.writeAsStringSync(data); - } - - /// Appends [data] to the end of file located at [fileAbsPath]. - /// - /// Creates the file if the file at [fileAbsPath] does not exist. - void appendDataToFile(String data, String fileAbsPath) { - var file = File(fileAbsPath); - if (file.existsSync()) { - file.writeAsStringSync(data, mode: FileMode.append); - } else { - writeDataToFile(data, fileAbsPath); - } - } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart index a601c9c7..d5123f49 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart @@ -1,14 +1,13 @@ +import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; class OrientationBuilderCommand extends FileStructureCommand { - final PATH_TO_ORIENTATION_BUILDER = - 'lib/widgets/responsive_orientation_builder.dart'; + final DIR_TO_ORIENTATION_BUILDER = 'lib/widgets/'; + final NAME_TO_ORIENTAION_BUILDER = 'responsive_orientation_builder.dart'; @override Future write(FileStructureStrategy strategy) { - var fileAbsPath = - '${strategy.GENERATED_PROJECT_PATH}$PATH_TO_ORIENTATION_BUILDER'; var template = ''' import 'package:flutter/material.dart'; @@ -51,6 +50,9 @@ class OrientationBuilderCommand extends FileStructureCommand { '''; - super.writeDataToFile(template, fileAbsPath); + strategy.writeDataToFile( + template, + p.join(strategy.GENERATED_PROJECT_PATH, DIR_TO_ORIENTATION_BUILDER), + NAME_TO_ORIENTAION_BUILDER); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 717343d3..13d1a8c8 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -6,14 +6,11 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; class ResponsiveLayoutBuilderCommand extends FileStructureCommand { - final PATH_TO_RESPONSIVE_LAYOUT = - 'lib/widgets/responsive_layout_builder.dart'; + final DIR_TO_RESPONSIVE_LAYOUT = 'lib/widgets/'; + final NAME_TO_RESPONSIVE_LAYOUT = 'responsive_layout_builder.dart'; @override Future write(FileStructureStrategy strategy) async { - var absPath = - '${strategy.GENERATED_PROJECT_PATH}$PATH_TO_RESPONSIVE_LAYOUT'; - var platforms = PBPlatformOrientationLinkerService() .platforms .map((platform) => platform.toString().split('.').last.toLowerCase()); @@ -22,12 +19,12 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { var breakpointChecks = _generateBreakpointStatements(platforms); var template = ''' class ResponsiveLayoutBuilder extends StatelessWidget { - ${widgetVars} + $widgetVars const ResponsiveLayoutBuilder( { Key key, - ${widgetInit} + $widgetInit } ); @@ -36,7 +33,7 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { return LayoutBuilder( builder: (context, constraints) { var width = constraints.maxWidth; - ${breakpointChecks} + $breakpointChecks return Container(); }, ); @@ -44,7 +41,8 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { } '''; - super.writeDataToFile(template, absPath); + strategy.writeDataToFile( + template, DIR_TO_RESPONSIVE_LAYOUT, NAME_TO_RESPONSIVE_LAYOUT); } String _generatePlatformWidgets(List platforms) { diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 6023bfc0..12c0414c 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -1,3 +1,4 @@ +import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -16,8 +17,8 @@ class WriteScreenCommand extends NodeFileStructureCommand { @override Future write(FileStructureStrategy strategy) { var absPath = - '${strategy.GENERATED_PROJECT_PATH}$SCREEN_PATH/$relativePath/$name'; - writeDataToFile(code, absPath); - return Future.value(absPath); + p.join(strategy.GENERATED_PROJECT_PATH, SCREEN_PATH, relativePath); + strategy.writeDataToFile(code, absPath, name); + return Future.value(p.join(absPath, name)); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index e620639d..ba39b402 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -1,3 +1,4 @@ +import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -13,8 +14,8 @@ class WriteSymbolCommand extends NodeFileStructureCommand { /// Returns path to the file that was created. @override Future write(FileStructureStrategy strategy) { - var absPath = '${strategy.GENERATED_PROJECT_PATH}$SYMBOL_PATH/$name'; - writeDataToFile(code, absPath); - return Future.value(absPath); + var absPath = p.join(strategy.GENERATED_PROJECT_PATH, SYMBOL_PATH); + strategy.writeDataToFile(code, absPath, name); + return Future.value(p.join(absPath, name)); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index c43e5caf..84fbfc24 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -1,4 +1,7 @@ import 'dart:io'; +import 'package:path/path.dart' as p; + +import 'package:parabeac_core/generation/flutter_project_builder/file_writer_observer.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; @@ -34,6 +37,13 @@ abstract class FileStructureStrategy implements CommandInvoker { final PBPageWriter _pageWriter; PBPageWriter get pageWriter => _pageWriter; + ///[FileWriterObserver] are observers that are notified everytime a new file + ///is created in the file in the file system + /// + ///A good example of an observer is the [ImportHelper], which keeps track + ///of the files relative location to handle their imports. + final List _fileObservers = []; + ///Indicator that signals if the required directories are constructed. /// ///Before generating any files, the caller must call the [setUpDirectories] @@ -47,6 +57,12 @@ abstract class FileStructureStrategy implements CommandInvoker { logger = Logger(runtimeType.toString()); } + void addFileObserver(FileWriterObserver observer) { + if (observer != null) { + _fileObservers.add(observer); + } + } + ///Setting up the required directories for the [FileStructureStrategy] to write the corresponding files. /// ///Default directories that are going to be generated is the @@ -104,4 +120,58 @@ abstract class FileStructureStrategy implements CommandInvoker { void commandCreated(FileStructureCommand command) { command.write(this); } + + /// Writing [data] into [directory] with the file [name] + /// + /// The [name] parameter should include the name of the file and the + /// extension of the file. For example, the [directory] 'temp/' contains + /// the file [name] of 'example.txt'. + /// The [UUID] is unique identifier of the file created in the [directory]. + /// If no [UUID] is specified, the [p.basenameWithoutExtension(path)] will + /// be used. + /// + /// [FileWriterObserver]s are going to be notfied of the new created file. + void writeDataToFile(String data, String directory, String name, + {String UUID}) { + var file = _getFile(directory, name); + file.createSync(recursive: true); + file.writeAsStringSync(data); + + _fileObservers.forEach((observer) => observer.fileCreated( + file.path, UUID ?? p.basenameWithoutExtension(file.path))); + } + + /// Appends [data] into [directory] with the file [name] + /// + /// The method is going to be identical to [writeDataToFile], however, + /// it going to try to append [data] to the file in the [directory]. If + /// no file is found, then its going to run [writeDataToFile]. [appendIfFound] flag + /// appends the information only if that information does not exist in the file. If no + /// [ModFile] function is found, its going to append the information at the end of the lines + void appendDataToFile(ModFile modFile, String directory, String name, + {String UUID, bool createFileIfNotFound = true}) { + var file = _getFile(directory, name); + if (file.existsSync()) { + var fileLines = file.readAsLinesSync(); + var modLines = modFile(fileLines); + + if (fileLines != modLines) { + file.writeAsStringSync(modFile(fileLines).toString()); + } + } else if (createFileIfNotFound) { + writeDataToFile(modFile([]).toString(), directory, name, UUID: UUID); + } + } + + File _getFile(String directory, String name) => File(p.join(directory, name)); } + +/// [Function] that returns the modified [lines] that should make the new data. +/// +/// _If the lines is empty, make sure you still return the data to be added, specially +/// if the file is going to be create._ +/// +/// This is used to insert data into an existing file in a specified location. +/// For example, when inserting a dart package into the `pubspec.yaml` file, the [ModFile] +/// [Function] is going to return the `List` that includes the new data. +typedef ModFile = List Function(List lines); diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart index 9fcef6f0..b72abc75 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart @@ -10,10 +10,10 @@ PBConfiguration _$PBConfigurationFromJson(Map json) { return PBConfiguration( json['widgetStyle'] as String ?? 'Material', json['widgetType'] as String ?? 'Stateless', - json['widgetSpacing'] as String ?? 'Expandeds', + json['widgetSpacing'] as String ?? 'Expanded', json['stateManagement'] as String ?? 'None', (json['layoutPrecedence'] as List)?.map((e) => e as String)?.toList() ?? - ['column', 'row', 'stacl'], + ['column', 'row', 'stack'], )..configurations = json['configurations'] as Map; } diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index ef32e8f0..fe62a5b9 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -24,5 +24,6 @@ class PBProject { {FileStructureStrategy fileStructureStrategy}) { _genProjectData = PBGenerationProjectData(); _fileStructureStrategy = fileStructureStrategy; + _genProjectData = PBGenerationProjectData(); } } diff --git a/test/lib/generation/commands/add_dependency_command_test.dart b/test/lib/generation/commands/add_dependency_command_test.dart index 95b6592b..a100f85f 100644 --- a/test/lib/generation/commands/add_dependency_command_test.dart +++ b/test/lib/generation/commands/add_dependency_command_test.dart @@ -9,16 +9,31 @@ import 'package:test/test.dart'; class MockFSStrategy extends Mock implements FileStructureStrategy {} +class MockCommand extends Mock implements AddDependencyCommand {} + +class MockFile extends Mock implements File {} + void main() { final path = '${Directory.current.path}/test/lib/generation/commands/'; group('Add Dependency Command', () { - FileStructureCommand command; + AddDependencyCommand command; FileStructureStrategy strategy; + List yamlFileContents; + File yamlFile; setUp(() { - command = AddDependencyCommand('auto_size_text', '^2.1.0'); + yamlFile = MockFile(); + command = MockCommand(); strategy = MockFSStrategy(); - when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); + yamlFileContents = ['dependencies:', 'flutter:', ' assets:']; + + when(command.package).thenReturn('auto_size_text'); + when(command.version).thenReturn('^2.1.0'); + when(command.yamlFile).thenReturn(yamlFile); + + when(yamlFile.readAsLinesSync()).thenReturn(yamlFileContents); + when(command.writeDataToFile('', '')).thenReturn(null); + when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst'); when(strategy.pageWriter).thenReturn(PBFlutterWriter()); }); diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index dd97e6ac..d5e1f349 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -71,6 +72,7 @@ void main() { when(project.projectName).thenReturn( '${Directory.current.path}/test/lib/output_services/temp2/'); when(project.forest).thenReturn([intermediateTree]); + when(project.genProjectData).thenReturn(PBGenerationProjectData()); when(project.projectAbsPath).thenReturn(outputPath); when(scaffold.child).thenReturn(container); From 115cb3261ba287f5bece0e2f534a040c7bc20a06 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Sat, 15 May 2021 16:46:35 -0600 Subject: [PATCH 079/404] Fixed all the unit test regarding the file structure commands and removed the necessary of writing to a file and reading the file. We can just intercept the edits and verify those are correct, we can assume that those external dependencies are working. --- .../commands/add_dependency_command.dart | 2 +- .../commands/add_constant_command_test.dart | 39 +++++++++-------- .../commands/add_dependency_command_test.dart | 43 ++++++++----------- .../commands/write_screen_command_test.dart | 24 +++++------ .../commands/write_symbol_command_test.dart | 31 ++++++------- 5 files changed, 65 insertions(+), 74 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart index c97f25d8..f73afed0 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -8,7 +8,7 @@ class AddDependencyCommand extends FileStructureCommand { final _PUBSPEC_YAML_NAME = 'pubspec.yaml'; ///assets yaml decleration - final String _ASSET_DECLERATION = ' assets:\n - assets/images/'; + final String _ASSET_DECLERATION = '\t\t- assets/images/'; /// Name of the [package] String package; diff --git a/test/lib/generation/commands/add_constant_command_test.dart b/test/lib/generation/commands/add_constant_command_test.dart index a19480d3..53a4c04d 100644 --- a/test/lib/generation/commands/add_constant_command_test.dart +++ b/test/lib/generation/commands/add_constant_command_test.dart @@ -4,38 +4,43 @@ import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:test/test.dart'; class MockFSStrategy extends Mock implements FileStructureStrategy {} void main() { - final path = '${Directory.current.path}/test/lib/generation/commands/'; group('Add Constant Command', () { var strategy; FileStructureCommand const1; + var const1V = ['c1', 'String', '\'test\'']; + FileStructureCommand const2; - setUp(() { - // Create temporary directory to output files - Process.runSync('mkdir', ['tmptst'], workingDirectory: path); + var const2V = ['c2', 'int', '20']; + setUp(() { strategy = MockFSStrategy(); - const1 = AddConstantCommand('c1', 'String', '\'test\''); - const2 = AddConstantCommand('c2', 'int', '20'); - when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); - when(strategy.pageWriter).thenReturn(PBFlutterWriter()); + const1 = AddConstantCommand(const1V[0], const1V[1], const1V[2]); + const2 = AddConstantCommand(const2V[0], const2V[1], const2V[2]); + when(strategy.GENERATED_PROJECT_PATH).thenReturn('temp/'); }); test('Testing Adding Constants To Project', () async { - final constPath = '${path}tmptst/lib/constants/constants.dart'; await const1.write(strategy); await const2.write(strategy); - expect(File(constPath).existsSync(), true); - var constFile = File(constPath).readAsStringSync(); - expect(constFile.contains('const String c1 = \'test\''), true); - expect(constFile.contains('const int c2 = 20'), true); - }); - tearDownAll(() { - Process.runSync('rm', ['-r', 'tmptst'], workingDirectory: path); + + var verification = + verify(strategy.appendDataToFile(captureAny, any, any)); + + var capturedFuncs = verification.captured.whereType(); + + var data = capturedFuncs + .map((ModFile mod) => mod([])) + .reduce((value, element) => value + element); + + expect(verification.callCount, 2); + expect(data, [ + 'const ${const1V[1]} ${const1V[0]} = ${const1V[2]};', + 'const ${const2V[1]} ${const2V[0]} = ${const2V[2]};' + ]); }); }); } diff --git a/test/lib/generation/commands/add_dependency_command_test.dart b/test/lib/generation/commands/add_dependency_command_test.dart index a100f85f..d673e5db 100644 --- a/test/lib/generation/commands/add_dependency_command_test.dart +++ b/test/lib/generation/commands/add_dependency_command_test.dart @@ -2,47 +2,40 @@ import 'dart:io'; import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:test/test.dart'; class MockFSStrategy extends Mock implements FileStructureStrategy {} -class MockCommand extends Mock implements AddDependencyCommand {} - class MockFile extends Mock implements File {} void main() { - final path = '${Directory.current.path}/test/lib/generation/commands/'; group('Add Dependency Command', () { AddDependencyCommand command; FileStructureStrategy strategy; - List yamlFileContents; - File yamlFile; + var package; + var version; setUp(() { - yamlFile = MockFile(); - command = MockCommand(); + package = 'auto_size_text'; + version = '^2.1.0'; + command = AddDependencyCommand(package, version); strategy = MockFSStrategy(); - yamlFileContents = ['dependencies:', 'flutter:', ' assets:']; - - when(command.package).thenReturn('auto_size_text'); - when(command.version).thenReturn('^2.1.0'); - when(command.yamlFile).thenReturn(yamlFile); - - when(yamlFile.readAsLinesSync()).thenReturn(yamlFileContents); - when(command.writeDataToFile('', '')).thenReturn(null); - when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst'); - when(strategy.pageWriter).thenReturn(PBFlutterWriter()); }); - test('Testing adding a dependency', () async { - await command.write(strategy); - var dependencies = strategy.pageWriter.dependencies; - expect(dependencies.isNotEmpty, true); - expect(dependencies.containsKey('auto_size_text'), true); - expect(dependencies['auto_size_text'], '^2.1.0'); + test('Testing the addition of package and asset path', () { + command.write(strategy); + var captured = verify(strategy.appendDataToFile(captureAny, any, any, + createFileIfNotFound: false)) + .captured + .first as ModFile; + expect(captured(['dependencies:', 'flutter:', ' assets:']), [ + 'dependencies:', + '$package: $version', + 'flutter:', + ' assets:', + '\t\t- assets/images/' + ]); }); }); } diff --git a/test/lib/generation/commands/write_screen_command_test.dart b/test/lib/generation/commands/write_screen_command_test.dart index 55d6baf5..d2ee842e 100644 --- a/test/lib/generation/commands/write_screen_command_test.dart +++ b/test/lib/generation/commands/write_screen_command_test.dart @@ -43,23 +43,21 @@ void main() { setUp(() { command = WriteScreenCommand('test_screen.dart', 'screens', screenData); strategy = MockFSStrategy(); - when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); - when(strategy.pageWriter).thenReturn(PBFlutterWriter()); + when(strategy.GENERATED_PROJECT_PATH).thenReturn('temp/'); }); test('Testing writing a screen', () async { - var screenPath = '${path}tmptst/lib/modules/screens/test_screen.dart'; - var screenFile = File(screenPath); - var commandPath = await command.write(strategy); + await command.write(strategy); + var verification = + verify(strategy.writeDataToFile(captureAny, any, captureAny)); - // The return of WriteScreenCommand is `String` - // ignore: unrelated_type_equality_checks - expect(screenPath == commandPath, true); - expect(screenFile.existsSync(), true); - expect(screenFile.readAsStringSync().contains(screenData), true); - }); - tearDownAll(() { - Process.runSync('rm', ['-r', 'tmptst'], workingDirectory: path); + /// Make sure we are writting to the file using the strategy + expect(verification.captured.first, screenData); + expect(verification.callCount, 1); + + ///Make sure that we are using the same name for the file that is going to + ///be written into the file system. + expect(verification.captured.contains('test_screen.dart'), isTrue); }); }); } diff --git a/test/lib/generation/commands/write_symbol_command_test.dart b/test/lib/generation/commands/write_symbol_command_test.dart index 1d789f80..25a4018d 100644 --- a/test/lib/generation/commands/write_symbol_command_test.dart +++ b/test/lib/generation/commands/write_symbol_command_test.dart @@ -1,16 +1,12 @@ -import 'dart:io'; - import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:test/test.dart'; class MockFSStrategy extends Mock implements FileStructureStrategy {} void main() { - final path = '${Directory.current.path}/test/lib/generation/commands/'; final symData = ''' import 'package:flutter/material.dart'; @@ -37,23 +33,22 @@ void main() { setUp(() { command = WriteSymbolCommand('test_symbol.dart', symData); strategy = MockFSStrategy(); - when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); - when(strategy.pageWriter).thenReturn(PBFlutterWriter()); + when(strategy.GENERATED_PROJECT_PATH).thenReturn('temp/'); }); - test('Testing writing a symbol', () async { - var screenPath = '${path}tmptst/lib/widgets/test_symbol.dart'; - var screenFile = File(screenPath); - var commandPath = await command.write(strategy); + test('Makes sure that the command is using the strategy to write a file', + () async { + await command.write(strategy); + var verification = + verify(strategy.writeDataToFile(captureAny, any, captureAny)); - // The return of WriteSymbolCommand is `String` - // ignore: unrelated_type_equality_checks - expect(screenPath == commandPath, true); - expect(screenFile.existsSync(), true); - expect(screenFile.readAsStringSync().contains(symData), true); - }); - tearDownAll(() { - Process.runSync('rm', ['-r', 'tmptst'], workingDirectory: path); + /// Make sure we are writting to the file using the strategy + expect(verification.captured.first, symData); + expect(verification.callCount, 1); + + ///Make sure that we are using the same name for the file that is going to + ///be written into the file system. + expect(verification.captured.contains('test_symbol.dart'), isTrue); }); }); } From 70c2fc80e20c40904761b3a46ea61dcdafc81245 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sun, 16 May 2021 16:23:21 -0700 Subject: [PATCH 080/404] find friendly name of the symbol instance from the last UUID in a path --- .../value_objects/pb_symbol_instance_overridable_value.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart index c30de146..a596a56a 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart @@ -1,4 +1,6 @@ import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; class PBSymbolInstanceOverridableValue { @@ -7,6 +9,8 @@ class PBSymbolInstanceOverridableValue { final String UUID; final dynamic value; + String get friendlyName => SN_UUIDtoVarName[PBInputFormatter.findLastOf(UUID, '/')] ?? 'noname'; + PBSymbolInstanceOverridableValue(this.UUID, this.value, this.type); static String _typeToJson(type) { From fe41e042c117435d7743d9c75441e920869a92e1 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sun, 16 May 2021 16:27:24 -0700 Subject: [PATCH 081/404] Fixed friendlyName to use last of UUID string as it could contain paths, and added quick map lookup for overrideable properties --- .../entities/pb_shared_master_node.dart | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 8cc1e2e0..e7d5d381 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -1,7 +1,9 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_mastersym_gen.dart'; +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -44,7 +46,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode ///The properties that could be be overridable on a [PBSharedMasterNode] List overridableProperties; - + Map overridePropMap = {}; String friendlyName; PBSharedMasterNode( @@ -93,7 +95,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode p.UUID, p.canOverride, p.propertyName, - /* Removed Parameter Defintion as it was accepting JSON?*/ + /* Removed Parameter Definition as it was accepting JSON?*/ null, // TODO: @Eddie currentContext.screenTopLeftCorner.x, currentContext.screenTopLeftCorner.y, @@ -102,6 +104,11 @@ class PBSharedMasterNode extends PBVisualIntermediateNode context: currentContext)) .toList() ..removeWhere((p) => p == null || p.parameterDefinition == null); + + // create quick lookup map for overridable properties by UUID + for (var override in overridableProperties) { + overridePropMap[override.UUID] = override; + } } @override @@ -132,7 +139,7 @@ class PBSharedParameterProp { dynamic get initialValue => _initialValue; final String _friendlyName; - String get friendlyName => _friendlyName; + String get friendlyName => _friendlyName ?? SN_UUIDtoVarName[PBInputFormatter.findLastOf(propertyName, '/')] ?? 'noname'; PBSharedParameterProp(this._friendlyName, this._type, this.value, this._canOverride, this._propertyName, this._UUID, this._initialValue); From c130ac783c4b62c24da3ddbc86e33ca66016c16f Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 17 May 2021 10:38:57 -0600 Subject: [PATCH 082/404] Corrected writing to .yaml file --- .../commands/add_dependency_command.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart index ee600046..03a42595 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -23,7 +23,7 @@ class AddDependencyCommand extends FileStructureCommand { } var line = readYaml.indexOf('dependencies:'); - readYaml.insert(++line, '$package: $version'); + readYaml.insert(++line, '\t$package: $version'); // TODO: we may want to move this to a separate Command to ensure it only gets called once. line = readYaml.indexOf('flutter:'); @@ -32,7 +32,11 @@ class AddDependencyCommand extends FileStructureCommand { readYaml.insert(++line, ' assets:\n - assets/images/'); } } + var buffer = StringBuffer(); - writeDataToFile(readYaml.toString(), yamlAbsPath); + for (var line in readYaml) { + buffer.writeln(line); + } + writeDataToFile(buffer.toString(), yamlAbsPath); } } From 05d8f99ce28428c32eed9307d1f403f3329c8d42 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 17 May 2021 10:39:24 -0600 Subject: [PATCH 083/404] Modify dependency adding test --- .../commands/add_dependency_command_test.dart | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/test/lib/generation/commands/add_dependency_command_test.dart b/test/lib/generation/commands/add_dependency_command_test.dart index 95b6592b..f74f4fe1 100644 --- a/test/lib/generation/commands/add_dependency_command_test.dart +++ b/test/lib/generation/commands/add_dependency_command_test.dart @@ -16,18 +16,27 @@ void main() { FileStructureStrategy strategy; setUp(() { + /// Create sample YAML file + var yaml = File('${path}tmptst/pubspec.yaml'); + yaml.createSync(recursive: true); + yaml.writeAsStringSync(''' +dependencies: + json_serializable: ^3.5.0 + +flutter: + '''); + command = AddDependencyCommand('auto_size_text', '^2.1.0'); strategy = MockFSStrategy(); - when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); + when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst'); when(strategy.pageWriter).thenReturn(PBFlutterWriter()); }); test('Testing adding a dependency', () async { await command.write(strategy); - var dependencies = strategy.pageWriter.dependencies; - expect(dependencies.isNotEmpty, true); - expect(dependencies.containsKey('auto_size_text'), true); - expect(dependencies['auto_size_text'], '^2.1.0'); + var fileStr = File('${path}tmptst/pubspec.yaml').readAsStringSync(); + expect(fileStr.contains('auto_size_text: ^2.1.0'), true); + expect(fileStr.contains('- assets/images/'), true); }); }); } From 889c408f02ab2b813414147323ca3326db8dd096 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 17 May 2021 10:40:52 -0600 Subject: [PATCH 084/404] Add cleanup to add dependency command --- test/lib/generation/commands/add_dependency_command_test.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/lib/generation/commands/add_dependency_command_test.dart b/test/lib/generation/commands/add_dependency_command_test.dart index f74f4fe1..6e80056f 100644 --- a/test/lib/generation/commands/add_dependency_command_test.dart +++ b/test/lib/generation/commands/add_dependency_command_test.dart @@ -38,5 +38,9 @@ flutter: expect(fileStr.contains('auto_size_text: ^2.1.0'), true); expect(fileStr.contains('- assets/images/'), true); }); + + tearDownAll(() { + Process.runSync('rm', ['-r', 'tmptst'], workingDirectory: path); + }); }); } From b9956c9b792831cee82018a03fae985925023228 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 17 May 2021 10:47:41 -0600 Subject: [PATCH 085/404] Add relative path checking for screen command --- .../commands/write_screen_command.dart | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 2ae20e0f..2ff37bcf 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -15,8 +15,13 @@ class WriteScreenCommand extends NodeFileStructureCommand { /// Returns path to the file that was created. @override Future write(FileStructureStrategy strategy) { - var absPath = - '${strategy.GENERATED_PROJECT_PATH}$SCREEN_PATH/$relativePath/$name'; + var absPath; + if (relativePath.isEmpty) { + absPath = '${strategy.GENERATED_PROJECT_PATH}$SCREEN_PATH/$name'; + } else { + absPath = + '${strategy.GENERATED_PROJECT_PATH}$SCREEN_PATH/$relativePath/$name'; + } writeDataToFile(code, absPath); return Future.value(absPath); } From 87beb0a51c2fb2ba9ca1c2d5e2fbdc563abffac1 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 17 May 2021 10:48:04 -0600 Subject: [PATCH 086/404] Alter write screen test with file structure --- test/lib/generation/commands/write_screen_command_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lib/generation/commands/write_screen_command_test.dart b/test/lib/generation/commands/write_screen_command_test.dart index 55d6baf5..ab10e2b8 100644 --- a/test/lib/generation/commands/write_screen_command_test.dart +++ b/test/lib/generation/commands/write_screen_command_test.dart @@ -41,14 +41,14 @@ void main() { FileStructureStrategy strategy; setUp(() { - command = WriteScreenCommand('test_screen.dart', 'screens', screenData); + command = WriteScreenCommand('test_screen.dart', '', screenData); strategy = MockFSStrategy(); when(strategy.GENERATED_PROJECT_PATH).thenReturn('${path}tmptst/'); when(strategy.pageWriter).thenReturn(PBFlutterWriter()); }); test('Testing writing a screen', () async { - var screenPath = '${path}tmptst/lib/modules/screens/test_screen.dart'; + var screenPath = '${path}tmptst/lib/screens/test_screen.dart'; var screenFile = File(screenPath); var commandPath = await command.write(strategy); From 41cf88a8674694ddf7776592930824afe0de06b5 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 17 May 2021 11:00:20 -0600 Subject: [PATCH 087/404] Add context to project builder test. --- test/lib/output_services/project_builder_test.dart | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index dd97e6ac..16984f37 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -9,6 +10,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_ import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; @@ -25,6 +27,8 @@ class MockProject extends Mock implements PBProject {} class MockData extends Mock implements IntermediateAuxiliaryData {} +class MockContext extends Mock implements PBContext {} + void main() { group('Project Builder Test', () { var projectBuilder; @@ -48,6 +52,8 @@ void main() { FileStructureStrategy fss; + MockContext context; + setUp(() async { MainInfo().cwd = Directory.current; MainInfo().outputPath = @@ -58,6 +64,7 @@ void main() { scaffold = MockScaffold(); container = MockContainer(); mockData = MockData(); + context = MockContext(); containerGenerator = PBContainerGenerator(); scaffoldGenerator = PBScaffoldGenerator(); @@ -72,6 +79,9 @@ void main() { '${Directory.current.path}/test/lib/output_services/temp2/'); when(project.forest).thenReturn([intermediateTree]); when(project.projectAbsPath).thenReturn(outputPath); + when(project.genProjectData).thenReturn(PBGenerationProjectData()); + + when(context.project).thenReturn(project); when(scaffold.child).thenReturn(container); when(scaffold.isHomeScreen).thenReturn(false); @@ -79,6 +89,7 @@ void main() { when(scaffold.name).thenReturn('testingPage'); when(scaffold.managerData).thenReturn(PBGenerationViewData()); when(scaffold.auxiliaryData).thenReturn(mockData); + when(scaffold.currentContext).thenReturn(context); when(container.generator).thenReturn(containerGenerator); when(container.auxiliaryData).thenReturn(mockData); From 71cf05ad5d625309020190f4847f8cb98cd20344 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Mon, 17 May 2021 12:04:20 -0700 Subject: [PATCH 088/404] Added layer styles to code and generates Styles.g.dart to handle layeredStyles from Sketch. Puts back layerStyle wrapper around TextStyle as well. --- lib/design_logic/pb_fill.dart | 4 +- lib/design_logic/pb_shared_master_node.dart | 2 +- .../flutter_project_builder.dart | 50 ++++++++- .../pb_box_decoration_gen_helper.dart | 1 + .../attribute-helper/pb_color_gen_helper.dart | 74 ++++++++++--- .../utils/middleware_utils.dart | 14 +-- .../symbols/pb_instancesym_gen.dart | 48 ++++++--- .../generators/symbols/pb_mastersym_gen.dart | 2 + .../generators/util/pb_input_formatter.dart | 9 ++ .../bloc_state_template_strategy.dart | 1 + .../stateless_template_strategy.dart | 4 +- .../visual-widgets/pb_container_gen.dart | 3 +- lib/input/figma/entities/layers/instance.dart | 4 +- .../figma/entities/style/figma_fill.dart | 3 + .../sketch/entities/layers/symbol_master.dart | 2 +- lib/input/sketch/entities/style/fill.dart | 3 +- .../sketch/entities/style/shared_style.dart | 100 +++++++++++++----- lib/input/sketch/entities/style/style.dart | 11 +- lib/input/sketch/helper/sketch_project.dart | 22 +++- .../sketch/helper/symbol_node_mixin.dart | 33 +++--- .../entities/inherited_container.dart | 6 ++ .../entities/pb_shared_instance.dart | 12 ++- .../pb_shared_aggregation_service.dart | 11 +- .../intermediate_auxillary_data.dart | 4 + 24 files changed, 320 insertions(+), 103 deletions(-) diff --git a/lib/design_logic/pb_fill.dart b/lib/design_logic/pb_fill.dart index 33861d56..35113753 100644 --- a/lib/design_logic/pb_fill.dart +++ b/lib/design_logic/pb_fill.dart @@ -3,7 +3,9 @@ import 'package:parabeac_core/design_logic/color.dart'; abstract class PBFill { PBColor color; bool isEnabled; - PBFill(this.color, [this.isEnabled = true]); + int fillType; + + PBFill(this.color, this.fillType, [this.isEnabled = true]); toJson(); } diff --git a/lib/design_logic/pb_shared_master_node.dart b/lib/design_logic/pb_shared_master_node.dart index 30949fe1..4be7ff46 100644 --- a/lib/design_logic/pb_shared_master_node.dart +++ b/lib/design_logic/pb_shared_master_node.dart @@ -90,7 +90,7 @@ class PBSharedMasterDesignNode extends DesignNode List sharedParameters = []; for (var prop in overrideProperties) { if (!ovrNames.contains(prop.overrideName)) { - var properties = AddMasterSymbolName(prop.overrideName, children); + var properties = AddMasterSymbolOverrideName(prop.overrideName, children); sharedParameters.add(PBSharedParameterProp( properties['name'], properties['type'], diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index ce766e37..f7d1bb57 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -111,12 +111,15 @@ class FlutterProjectBuilder { try { Directory('${pathToFlutterProject}lib/document/') .createSync(recursive: true); + + WriteStyleClasses(); + var s = File('${pathToFlutterProject}lib/document/shared_props.g.dart') .openWrite(mode: FileMode.write, encoding: utf8); s.write('''import 'dart:ui'; import 'package:flutter/material.dart'; - + import 'Styles.g.dart'; '''); for (var sharedStyle in mainTree.sharedStyles) { s.write(sharedStyle.generate() + '\n'); @@ -166,3 +169,48 @@ class FlutterProjectBuilder { ); } } + +void WriteStyleClasses() +{ + var s = File('${pathToFlutterProject}lib/document/Styles.g.dart') + .openWrite(mode: FileMode.write, encoding: utf8); + s.write(''' +import 'dart:ui'; +import 'package:flutter/material.dart'; + +class SK_Fill { + Color color; + bool isEnabled; + SK_Fill(this.color, [this.isEnabled = true]); +} + +class SK_Border { + bool isEnabled; + double fillType; + Color color; + double thickness; + SK_Border(this.isEnabled, this.fillType, this.color, this.thickness); +} + +class SK_BorderOptions { + bool isEnabled; + List dashPattern; + int lineCapStyle; + int lineJoinStyle; + SK_BorderOptions(this.isEnabled, this.dashPattern, this.lineCapStyle, this.lineJoinStyle); +} + +class SK_Style { + Color backgroundColor; + List fills; + List borders; + SK_BorderOptions borderOptions; + TextStyle textStyle; + bool hasShadow; + SK_Style(this.backgroundColor, this.fills, this.borders, this.borderOptions,this.textStyle, [this.hasShadow = false]); +} +'''); + + s.close(); + +} diff --git a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart index aca43a24..dc7013b8 100644 --- a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart @@ -13,6 +13,7 @@ class PBBoxDecorationHelper extends PBAttributesHelper { if (source is InheritedContainer) { final buffer = StringBuffer(); buffer.write('decoration: BoxDecoration('); + buffer.write(PBColorGenHelper().generate(source, generatorContext)); var borderInfo = source.auxiliaryData.borderInfo; if (source.auxiliaryData.color != null) { buffer.write(PBColorGenHelper().generate(source, generatorContext)); diff --git a/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart index e0a65d45..9a78643c 100644 --- a/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart @@ -14,29 +14,69 @@ class PBColorGenHelper extends PBAttributesHelper { if (source == null) { return statement; } - if (source is InheritedScaffold) { - var scaffold = source; - if (scaffold.auxiliaryData.color == null) { + if (source.auxiliaryData.style != null) { + if (source is InheritedScaffold) { + var scaffold = source; + if (scaffold.auxiliaryData.color == null) { + statement = ''; + } else { + statement = findDefaultColor(scaffold.auxiliaryData.color) != null + ? 'backgroundColor: ${findDefaultColor( + scaffold.auxiliaryData.color)},\n' + : 'backgroundColor: Color(${scaffold + .auxiliaryData.color}),\n'; + } + } else if (source.auxiliaryData.color == null) { statement = ''; } else { - statement = findDefaultColor(scaffold.auxiliaryData.color) != null - ? 'backgroundColor: ${findDefaultColor(scaffold.auxiliaryData.color)},' - : 'backgroundColor: Color(${scaffold.auxiliaryData.color}),\n'; + if (source is! InheritedContainer) { + statement = findDefaultColor(source.auxiliaryData.color) != null + ? 'color: ${findDefaultColor( + source.auxiliaryData.color)},\n' + : 'color: Color(${source + .auxiliaryData.color}),\n'; + } else if ((source as InheritedContainer).isBackgroundVisible) { + statement = findDefaultColor(source.auxiliaryData.color) != null + ? 'color: ${findDefaultColor( + source.auxiliaryData.color)},\n' + : 'color: Color(${source + .auxiliaryData.color}),\n'; + } else { + statement = ''; + } } - } else if (source.auxiliaryData.color == null) { - statement = ''; } else { - if (source is! InheritedContainer) { - statement = findDefaultColor(source.auxiliaryData.color) != null - ? 'color: ${findDefaultColor(source.auxiliaryData.color)},' - : 'color: Color(${source.auxiliaryData.color}),\n'; - } else if ((source as InheritedContainer).isBackgroundVisible) { - statement = findDefaultColor(source.auxiliaryData.color) != null - ? 'color: ${findDefaultColor(source.auxiliaryData.color)},' - : 'color: Color(${source.auxiliaryData.color}),\n'; - } else { + if (source is InheritedScaffold) { + var scaffold = source; + if (scaffold.auxiliaryData.color == null) { + statement = ''; + } else { + statement = findDefaultColor(scaffold.auxiliaryData.color) != null + ? 'backgroundColor: ${findDefaultColor( + scaffold.auxiliaryData.color)},\n' + : 'backgroundColor: Color(${scaffold + .auxiliaryData.color}),\n'; + } + } else if (source.auxiliaryData.color == null) { statement = ''; + } else { + if (source is! InheritedContainer) { + statement = findDefaultColor(source.auxiliaryData.color) != null + ? 'color: ${findDefaultColor( + source.auxiliaryData.color)},\n' + : 'color: Color(${source + .auxiliaryData.color}),\n'; + } else if ((source as InheritedContainer).isBackgroundVisible) { + statement = findDefaultColor(source.auxiliaryData.color) != null + ? 'color: ?? ${findDefaultColor( + source.auxiliaryData.color)},\n' + : 'color: Color(${source + .auxiliaryData.color}),\n'; + } else { + statement = ''; + } } + } return statement; } diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 8271edac..e6f80a89 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:recase/recase.dart'; @@ -17,9 +18,9 @@ class MiddlewareUtils { if (node is PBSharedMasterNode && (node.overridableProperties?.isNotEmpty ?? false)) { - node.overridableProperties.forEach((property) { - overrideVars += 'final ${property.friendlyName};'; - overrideAttr += 'this.${property.friendlyName}, '; + node.overridableProperties.forEach((prop) { + overrideVars += 'final ${prop.friendlyName};'; + overrideAttr += 'this.${prop.friendlyName}, '; }); stateBuffer.write(MiddlewareUtils.generateEmptyVariable(node)); stateInitializers.write( @@ -33,9 +34,10 @@ class MiddlewareUtils { if (variationNode is PBSharedMasterNode && (variationNode.overridableProperties?.isNotEmpty ?? false)) { - variationNode.overridableProperties.forEach((property) { - overrideVars += 'final ${property.friendlyName};'; - overrideAttr += 'this.${property.friendlyName}, '; + variationNode.overridableProperties.forEach((prop) { + var friendlyName = SN_UUIDtoVarName[prop.propertyName] ?? 'NOTFOUND'; + overrideVars += 'final $friendlyName;'; + overrideAttr += 'this.$friendlyName, '; }); stateBuffer.write(MiddlewareUtils.generateEmptyVariable(variationNode)); stateInitializers.write( diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index e50939f6..c053d087 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; +import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/entities/style/text_style.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; @@ -48,11 +49,11 @@ class PBSymbolInstanceGenerator extends PBGenerator { buffer.write(method_signature); buffer.write('('); buffer.write('constraints,'); - + for (var param in source.sharedParamValues ?? []) { switch (param.type) { case PBSharedInstanceIntermediateNode: - String siString = genSymbolInstance( + var siString = genSymbolInstance( param.UUID, param.value, source.overrideValues, @@ -71,11 +72,20 @@ class PBSymbolInstanceGenerator extends PBGenerator { source.currentContext.treeRoot.data.addImport( 'package:${MainInfo().projectName}/document/shared_props.g.dart'); buffer.write( - '${param.name}: ${SharedStyle_UUIDToName[param.value] ?? "TextStyle()"},'); + '${param.name}: ${SharedStyle_UUIDToName[param.value]}.textStyle,'); break; - default: + case Style: + // hack to include import + source.currentContext.treeRoot.data.addImport( + 'package:${MainInfo().projectName}/document/shared_props.g.dart'); + buffer.write( + '${param.name}: ${SharedStyle_UUIDToName[param.value]},'); + break; + case String: buffer.write('${param.name}: \"${param.value}\",'); break; + default: + log.info('Unknown type ${param.type.toString()} in parameter values for symbol instance.\n'); } } // end of return function(); @@ -124,13 +134,10 @@ class PBSymbolInstanceGenerator extends PBGenerator { return ''; } - // include import - Set path = PBGenCache().getPaths(masterSymbol.SYMBOL_ID); - if (path.isEmpty) { - log.warning("Can't find path for Master Symbol with UUID: ${UUID}"); - } else { - managerData.addImport(path.first); - } + + var fileName = masterSymbol.name.snakeCase; + managerData.addImport( + 'package:${MainInfo().projectName}/view/symbols/${fileName}.dart'); var buffer = StringBuffer(); buffer.write('${masterSymbol.friendlyName}(constraints, '); @@ -145,21 +152,28 @@ class PBSymbolInstanceGenerator extends PBGenerator { ovrValue.value, ovrUUID, overrideValues, managerData, depth: depth + 1)); - break; case InheritedBitmap: var name = SN_UUIDtoVarName[ovrUUID + '_image']; - buffer.write('${name}: \"assets/${ovrValue.value["_ref"]}\",'); + buffer.write('$name: \"assets/${ovrValue.value["_ref"]}\",'); break; case TextStyle: var name = SN_UUIDtoVarName[ovrUUID + '_textStyle']; buffer.write( - '${name}: ${SharedStyle_UUIDToName[ovrValue.value] ?? "TextStyle()"},'); + '$name: ${SharedStyle_UUIDToName[ovrValue.value]}.textStyle,'); break; - default: - var name = SN_UUIDtoVarName[ovrUUID]; - buffer.write('${name}: \"${ovrValue.value}\",'); + case Style: + //var name = SN_UUIDtoVarName[ovrUUID + '_layerStyle']; + //buffer.write( + // 'layerStyle: ${SharedStyle_UUIDToName[ovrValue.value]},'); + break; + case String: + var name = SN_UUIDtoVarName[ovrUUID + '_stringValue'] ; + buffer.write('$name: \"${ovrValue.value}\",'); break; + default: + log.info('Unknown type ${ovrValue.type.toString()} in override values for symbol instance.\n'); + } } } diff --git a/lib/generation/generators/symbols/pb_mastersym_gen.dart b/lib/generation/generators/symbols/pb_mastersym_gen.dart index a8787537..463aa370 100644 --- a/lib/generation/generators/symbols/pb_mastersym_gen.dart +++ b/lib/generation/generators/symbols/pb_mastersym_gen.dart @@ -18,6 +18,8 @@ class PBMasterSymbolGenerator extends PBGenerator { if (source.child == null) { return ''; } + // override styles if need be. + source.child.currentContext = source.currentContext; // see if widget itself is overridden, need to pass var generatedWidget = diff --git a/lib/generation/generators/util/pb_input_formatter.dart b/lib/generation/generators/util/pb_input_formatter.dart index f581bd00..9559ef35 100644 --- a/lib/generation/generators/util/pb_input_formatter.dart +++ b/lib/generation/generators/util/pb_input_formatter.dart @@ -47,4 +47,13 @@ class PBInputFormatter { str.startsWith(RegExp(r'^[\d]+')) ? str.replaceFirstMapped(RegExp(r'^[\d]+'), (e) => '') : str; + + /// Method that splits `target` according to `delimeter` + /// and returns the last entry in the list. + static String findLastOf(String target, String delimeter) { + if (target == null || delimeter == null) { + return ''; + } + return target.split(delimeter).last; + } } diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index 9a46fd47..ebda2aa1 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:recase/recase.dart'; diff --git a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart index 6e39d7cc..405537e1 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:recase/recase.dart'; @@ -14,6 +15,7 @@ class StatelessTemplateStrategy extends TemplateStrategy { var returnStatement = node.generator.generate(node, generatorContext); var overrides = ''; var overrideVars = ''; + if (node is PBSharedMasterNode && node.overridableProperties.isNotEmpty) { node.overridableProperties.forEach((prop) { overrides += 'this.${prop.friendlyName}, '; @@ -21,7 +23,7 @@ class StatelessTemplateStrategy extends TemplateStrategy { }); } return ''' -${manager.generateImports()} + ${manager.generateImports()} class ${widgetName.pascalCase} extends StatelessWidget{ ${node is PBSharedMasterNode ? 'final constraints;' : ''} diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index 60552e73..f020d669 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -22,7 +22,8 @@ class PBContainerGenerator extends PBGenerator { if (source.auxiliaryData.borderInfo != null && source.auxiliaryData.borderInfo.isNotEmpty) { buffer.write(PBBoxDecorationHelper().generate(source, generatorContext)); - } else { + } + else { buffer.write(PBColorGenHelper().generate(source, generatorContext)); } diff --git a/lib/input/figma/entities/layers/instance.dart b/lib/input/figma/entities/layers/instance.dart index 6c5d419b..d8694fa9 100644 --- a/lib/input/figma/entities/layers/instance.dart +++ b/lib/input/figma/entities/layers/instance.dart @@ -106,8 +106,8 @@ class Instance extends FigmaFrame String pbdfType = 'symbol_instance'; @override - Map AddMasterSymbolName(String overrideName, List children) { - // TODO: implement AddMasterSymbolName + Map AddMasterSymbolOverrideName(String overrideName, List children) { + // TODO: implement AddMasterSymbolOverrideName throw UnimplementedError(); } diff --git a/lib/input/figma/entities/style/figma_fill.dart b/lib/input/figma/entities/style/figma_fill.dart index 1ef4bd81..4fae2f60 100644 --- a/lib/input/figma/entities/style/figma_fill.dart +++ b/lib/input/figma/entities/style/figma_fill.dart @@ -9,6 +9,9 @@ class FigmaFill implements PBFill { @override PBColor color; + @override + int fillType; + FigmaFill(FigmaColor this.color, [this.isEnabled = true]); @override diff --git a/lib/input/sketch/entities/layers/symbol_master.dart b/lib/input/sketch/entities/layers/symbol_master.dart index 6ae1cd25..303ad310 100644 --- a/lib/input/sketch/entities/layers/symbol_master.dart +++ b/lib/input/sketch/entities/layers/symbol_master.dart @@ -168,7 +168,7 @@ class SymbolMaster extends AbstractGroupLayer List sharedParameters = []; for (var prop in overrideProperties) { if (!ovrNames.contains(prop.overrideName)) { - var properties = AddMasterSymbolName(prop.overrideName, children); + var properties = AddMasterSymbolOverrideName(prop.overrideName, children); sharedParameters.add(PBSharedParameterProp( properties['name'], properties['type'], diff --git a/lib/input/sketch/entities/style/fill.dart b/lib/input/sketch/entities/style/fill.dart index 022252ac..e963b4a0 100644 --- a/lib/input/sketch/entities/style/fill.dart +++ b/lib/input/sketch/entities/style/fill.dart @@ -12,7 +12,8 @@ class Fill implements PBFill { final String classField; @override bool isEnabled; - final int fillType; + @override + int fillType; @override PBColor color; final ContextSettings contextSettings; diff --git a/lib/input/sketch/entities/style/shared_style.dart b/lib/input/sketch/entities/style/shared_style.dart index 04078970..709cf390 100644 --- a/lib/input/sketch/entities/style/shared_style.dart +++ b/lib/input/sketch/entities/style/shared_style.dart @@ -27,40 +27,92 @@ class SharedStyle with PBColorMixin { this.style, }) { name = name.camelCase; - SharedStyle_UUIDToName[UUID] = name.replaceAll(RegExp(r'[^A-Za-z0-9_]',), ''); + SharedStyle_UUIDToName[UUID] = name.replaceAll( + RegExp( + r'[^A-Za-z0-9_]', + ), + ''); } String generate() { - var buffer = StringBuffer(); if (style != null) { - // TODO: implement SharedStyle.style to flutter style parameters. - if (style.textStyle != null) { - var source = style.textStyle; - var fontDescriptor = source.fontDescriptor as FontDescriptor; - buffer.write('TextStyle ${name} = TextStyle(\n'); - if (fontDescriptor.fontName != null) { - buffer.write('fontFamily: \'${source.fontDescriptor.fontName}\',\n'); + buffer.write('SK_Style ${name} = SK_Style(\n'); + var bgc = style.backgroundColor; + if (bgc == null) { + buffer.write('null,\t\t// backgroundColor\n'); + } else { + buffer.write( + 'Color.fromARGB(${(bgc.alpha * 255.0).toInt()}, ${(bgc.red * 255.0).toInt()}, ${(bgc.green * 255.0).toInt()}, ${(bgc.blue * 255.0).toInt()}),\n'); + } + + var fills = style.fills; + if (fills == null) { + buffer.write('null,\t\t// List\n'); + } else { + buffer.write('[\n'); + fills.forEach((fill) { + buffer.write('SK_Fill('); + if (fill.color == null) { + buffer.write('null, ${fill.isEnabled})\t\t// fill.color\n'); + } else { + buffer.write( + 'Color.fromARGB(${(fill.color.alpha * 255.0).toInt()}, ${(fill.color.red * 255.0).toInt()}, ${(fill.color.green * 255.0).toInt()}, ${(fill.color.blue * 255.0).toInt()}), ${fill.isEnabled})\n'); + } + }); + buffer.write('],\n'); + } + var borders = style.borders; + if (borders == null) { + buffer.write('null,\t\t// borders\n'); + } else { + buffer.write('[\n'); + borders.forEach((border) { + buffer.write('SK_Border(${border.isEnabled}, ${border.fillType}, '); + if (border.color == null) { + buffer.write('null,\t\t// border.color\n'); + } else { + buffer.write( + 'Color.fromARGB(${(border.color.alpha * 255.0).toInt()}, ${(border.color.red * 255.0).toInt()}, ${(border.color.green * 255.0).toInt()}, ${(border.color.blue * 255.0).toInt()}), ${border.thickness}),\n'); + } + }); + buffer.write('],\n'); + } + var bo = style.borderOptions; + if (bo == null) { + buffer.write('null,,\t\t// borderOptions\n'); + } else { + // TODO if dashPattern is used figure out how to export, using null for now + buffer.write( + 'SK_BorderOptions(${bo.isEnabled}, null, ${bo.lineCapStyle}, ${bo.lineJoinStyle}),\n'); + } + + if (style.textStyle == null) { + buffer.write('null,\t\t// textStyle\n'); + } else { + var ts = style.textStyle; + var fd = ts.fontDescriptor as FontDescriptor; + buffer.write('TextStyle(\n'); + if (fd.fontName != null) { + buffer.write('fontFamily: \'${fd.fontName}\',\n'); } - if (fontDescriptor.fontSize != null) { - buffer.write('fontSize: ${fontDescriptor.fontSize.toString()},\n'); + if (fd.fontSize != null) { + buffer.write('fontSize: ${fd.fontSize.toString()},\n'); } - if (fontDescriptor.fontWeight != null) { - buffer.write( - 'fontWeight: FontWeight.${fontDescriptor.fontWeight - .toString()},\n'); + if (fd.fontWeight != null) { + buffer.write('fontWeight: FontWeight.${fd.fontWeight.toString()},\n'); } - if (fontDescriptor.fontStyle != null) { - buffer.write('fontStyle: FontStyle.${fontDescriptor.fontStyle},\n'); + if (fd.fontStyle != null) { + buffer.write('fontStyle: FontStyle.${fd.fontStyle},\n'); } - if (fontDescriptor.letterSpacing != null) { - buffer.write('letterSpacing: ${fontDescriptor.letterSpacing},\n'); + if (fd.letterSpacing != null) { + buffer.write('letterSpacing: ${fd.letterSpacing},\n'); } - if (source.fontColor != null) { - var color = toHex(source.fontColor); + if (ts.fontColor != null) { + var color = toHex(ts.fontColor); var defColor = findDefaultColor(color); if (defColor == null) { buffer.write('color: Color(${color}),'); @@ -69,15 +121,15 @@ class SharedStyle with PBColorMixin { } } - buffer.write(');\n'); + buffer.write('),\n'); } + buffer.write('${style.hasShadow});\n'); } return buffer.toString(); - } factory SharedStyle.fromJson(Map json) => _$SharedStyleFromJson(json); - Map toJson() => _$SharedStyleToJson(this); + Map toJson() => _$SharedStyleToJson(this); } diff --git a/lib/input/sketch/entities/style/style.dart b/lib/input/sketch/entities/style/style.dart index dba78310..d8343b47 100644 --- a/lib/input/sketch/entities/style/style.dart +++ b/lib/input/sketch/entities/style/style.dart @@ -31,6 +31,7 @@ class Style implements PBStyle { final List borders; final ColorControls colorControls; final ContextSettings contextSettings; + @override List fills, innerShadows, shadows; @JsonKey(nullable: true) PBTextStyle textStyle; @@ -51,12 +52,20 @@ class Style implements PBStyle { this.startMarkerType, this.windingRule, TextStyle this.textStyle, + this.backgroundColor, + this.hasShadow, }) { if (shadows != null) { - this.shadows = null; + //this.shadows = null; this.innerShadows = null; hasShadow = true; } + // TODO: add rectangle fill types, for now just copy the fill[0] to the background color + if (fills.length >= 1) { + if (fills[0].isEnabled && (fills[0].fillType == 0)) { + backgroundColor = fills[0].color; + } + } } factory Style.fromJson(Map json) => _$StyleFromJson(json); diff --git a/lib/input/sketch/helper/sketch_project.dart b/lib/input/sketch/helper/sketch_project.dart index 4601b959..ce18473c 100644 --- a/lib/input/sketch/helper/sketch_project.dart +++ b/lib/input/sketch/helper/sketch_project.dart @@ -26,6 +26,9 @@ class SketchProject extends DesignProject { final InputDesignService _ids; Archive _originalArchive; final Map _pagesAndArtboards; + // Map to prevent name collisions + Map layerNames = {}; + SketchProject(this._ids, this._pagesAndArtboards, this.projectName) { id = _ids.documentFile['do_objectID']; _originalArchive = _ids.archive; @@ -46,7 +49,7 @@ class SketchProject extends DesignProject { var LayerStyles = doc.layerStyles['objects'] ?? []; for (var sharedStyle in LayerStyles) { var layerStyle = SharedStyle.fromJson(sharedStyle); - layerStyle.name = PBInputFormatter.formatVariable(layerStyle.name); + layerStyle.name = GetUniqueLayerName(layerStyle.name.camelCase); sharedStyles.add(layerStyle); } } @@ -56,8 +59,7 @@ class SketchProject extends DesignProject { for (var sharedStyle in LayerTextStyles) { var layerTextStyle = SharedStyle.fromJson(sharedStyle); - layerTextStyle.name = - PBInputFormatter.formatVariable(layerTextStyle.name.camelCase); + layerTextStyle.name = GetUniqueLayerName(layerTextStyle.name.camelCase); sharedStyles.add(layerTextStyle); } } @@ -131,4 +133,18 @@ class SketchProject extends DesignProject { } return sketchPages; } + + String GetUniqueLayerName(String layerStyleName) { + var name = PBInputFormatter.formatVariable(layerStyleName); + var count = 0; + if (layerNames.containsKey(name)) { + count = layerNames[name] + 1; + name += count.toString(); + } + + layerNames[name] = count; + + return name; + } + } diff --git a/lib/input/sketch/helper/symbol_node_mixin.dart b/lib/input/sketch/helper/symbol_node_mixin.dart index 0b341919..42b45f5b 100644 --- a/lib/input/sketch/helper/symbol_node_mixin.dart +++ b/lib/input/sketch/helper/symbol_node_mixin.dart @@ -1,4 +1,5 @@ import 'dart:core'; +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; @@ -43,26 +44,28 @@ mixin SymbolNodeMixin { return null; } - Map AddMasterSymbolName(String overrideName, List children) { + Map AddMasterSymbolOverrideName(String overrideName, List children) { var varName; var parmInfo = extractParameter(overrideName); var uuid = parmInfo['uuid']; - var nodeName = FindName(uuid, children, parmInfo['type']) ?? 'var'; - // only increase count, make new varName if unique UUID - if (!SN_UUIDtoVarName.containsKey(overrideName)) { - var count = varNameCount[nodeName] ?? 0; - varName = nodeName; - varNameCount[nodeName] = count + 1; - // first one doesn't have appended number - if (count > 0) { - varName += count.toString(); + var nodeName = FindName(uuid, children, parmInfo['type']); + // only add names of our direct descendants + if (nodeName != null) { + // only increase count, make new varName if unique UUID + if (!SN_UUIDtoVarName.containsKey(overrideName)) { + var count = varNameCount[nodeName] ?? 0; + varName = nodeName; + varNameCount[nodeName] = count + 1; + // first one doesn't have appended number + if (count > 0) { + varName += count.toString(); + } + SN_UUIDtoVarName[overrideName] = varName; + } else { + varName = SN_UUIDtoVarName[overrideName]; } - SN_UUIDtoVarName[overrideName] = varName; - } else { - varName = SN_UUIDtoVarName[overrideName]; } - return {'name': varName, 'type': parmInfo['type'], 'uuid': uuid}; } @@ -89,7 +92,7 @@ mixin SymbolNodeMixin { case 'textStyle': type = TextStyle; break; - case 'style': + case 'layerStyle': type = Style; break; default: diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index ee2b67d9..03edeae2 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -45,13 +45,19 @@ class InheritedContainer extends PBVisualIntermediateNode 'height': originalRef.boundaryRectangle.height, }; + // have to save this in case it is overridden + auxiliaryData.style = originalRef.style; + if (originalRef.style != null && originalRef.style.fills.isNotEmpty) { for (var fill in originalRef.style.fills) { if (fill.isEnabled) { auxiliaryData.color = toHex(fill.color); + // use the first one found. + break; } } } + auxiliaryData.alignment = alignX != null && alignY != null ? {'alignX': alignX, 'alignY': alignY} : null; diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 285339dd..8d676433 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_instancesym_gen.dart'; +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -36,7 +37,9 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; - List overrideValues; + List overrideValues; + + Map sharedValuesMap = {}; PBSharedInstanceIntermediateNode( this.originalRef, @@ -65,6 +68,11 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode .map((v) => PBSymbolInstanceOverridableValue(v.UUID, v.value, v.type)) .toList() ..removeWhere((v) => v == null || v.value == null); + + //for (var sharedParam in sharedParamValues) { + // sharedValuesMap[sharedParam.overrideName] = sharedParam; + //} + } @override @@ -96,7 +104,7 @@ class PBSharedParameterValue { final String _overrideName; String get overrideName => _overrideName; - String get name => SN_UUIDtoVarName[_overrideName]; + String get name => SN_UUIDtoVarName[PBInputFormatter.findLastOf(_overrideName, '/')]; PBSharedParameterValue( this._type, diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index a69cf8d2..7cd0ae08 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -47,7 +48,7 @@ class PBSharedInterAggregationService { void gatherSharedParameters( PBSharedMasterNode sharedMasterNode, PBIntermediateNode rootChildNode) { for (var prop in sharedMasterNode.overridableProperties) { - var targetUUID = _findLastOf(prop?.UUID, '/'); + var targetUUID = PBInputFormatter.findLastOf(prop?.UUID, '/'); prop.value = PBIntermediateNodeSearcherService.searchNodeByUUID( rootChildNode, targetUUID); if (prop.value == null) { @@ -111,12 +112,4 @@ class PBSharedInterAggregationService { PBSharedMasterNode _searchMasterNode(String masterUUID) => _symbolStorage.getSharedMasterNodeBySymbolID(masterUUID); - /// Method that splits `target` according to `delimeter` - /// and returns the last entry in the list. - String _findLastOf(String target, String delimeter) { - if (target == null || delimeter == null) { - return ''; - } - return target.split(delimeter).last; - } } diff --git a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart index ad1c6abe..3673a5c7 100644 --- a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart +++ b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/directed_state_graph.dart'; class IntermediateAuxiliaryData { @@ -12,6 +13,9 @@ class IntermediateAuxiliaryData { /// The background color of the element. String color; + /// the style of the element (which can be overridden) + Style style; + IntermediateAuxiliaryData({ this.stateGraph, this.alignment, From e6675dcb549cb0484ab283384ed852e6502bc717 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Mon, 17 May 2021 13:36:48 -0600 Subject: [PATCH 089/404] Applyed automated fix by dart. --- lib/controllers/controller.dart | 2 +- lib/controllers/design_controller.dart | 4 ++-- lib/controllers/figma_controller.dart | 4 ++-- lib/controllers/sketch_controller.dart | 2 +- lib/design_logic/artboard.dart | 1 + lib/design_logic/boolean_operation.dart | 4 ++-- lib/design_logic/image.dart | 4 ++-- lib/design_logic/oval.dart | 2 ++ .../pb_shared_instance_design_node.dart | 4 ++-- lib/design_logic/pb_shared_master_node.dart | 7 ++++--- lib/design_logic/polygon.dart | 2 ++ lib/design_logic/vector.dart | 3 ++- lib/eggs/injected_app_bar.dart | 4 +++- lib/eggs/injected_tab_bar.dart | 3 +++ .../flutter_project_builder.dart | 2 +- .../generators/layouts/pb_row_gen.dart | 2 +- .../state_management/bloc_middleware.dart | 14 ++++++------- .../state_management/provider_middleware.dart | 20 +++++++++---------- .../state_management/riverpod_middleware.dart | 4 ++-- .../state_management/stateful_middleware.dart | 8 ++++---- .../utils/middleware_utils.dart | 16 +++++++-------- .../generators/pb_flutter_generator.dart | 3 ++- .../generators/plugins/pb_plugin_node.dart | 2 ++ .../symbols/pb_instancesym_gen.dart | 12 +++++------ .../pb_file_structure_strategy.dart | 16 +++++++-------- .../provider_file_structure_strategy.dart | 6 +++--- .../riverpod_file_structure_strategy.dart | 6 +++--- .../pb_generation_configuration.dart | 12 +++++------ ...platform_orientation_generation_mixin.dart | 7 +------ .../bloc_state_template_strategy.dart | 4 ++-- .../stateful_template_strategy.dart | 10 +++++----- .../stateless_template_strategy.dart | 2 +- .../generators/writers/pb_flutter_writer.dart | 6 +++--- .../prototyping/pb_prototype_gen.dart | 2 +- .../pb_prototype_linker_service.dart | 8 ++++---- .../prototyping/pb_prototype_storage.dart | 2 +- .../entities/layers/boolean_operation.dart | 1 + lib/input/figma/entities/layers/canvas.dart | 1 + .../figma/entities/layers/component.dart | 4 ++-- lib/input/figma/entities/layers/ellipse.dart | 1 + .../layers/figma_paragraph_style.dart | 1 + lib/input/figma/entities/layers/group.dart | 2 +- .../figma/entities/style/figma_border.dart | 1 + .../entities/style/figma_border_options.dart | 1 + .../figma/entities/style/figma_fill.dart | 1 + .../figma/entities/style/figma_style.dart | 5 +++-- .../entities/style/figma_text_style.dart | 1 + lib/input/figma/helper/api_call_service.dart | 8 ++++---- lib/input/figma/helper/api_exceptions.dart | 9 +++++---- lib/input/figma/helper/style_extractor.dart | 4 ++-- .../helper/asset_processing_service.dart | 2 +- lib/input/helper/azure_asset_service.dart | 14 ++++++------- lib/input/helper/design_page.dart | 4 ++-- lib/input/helper/design_project.dart | 4 ++-- lib/input/helper/design_screen.dart | 2 +- .../entities/layers/abstract_group_layer.dart | 2 +- .../entities/layers/abstract_layer.dart | 5 ++++- .../sketch/entities/layers/artboard.dart | 7 ++++--- lib/input/sketch/entities/layers/bitmap.dart | 4 ++-- lib/input/sketch/entities/layers/group.dart | 4 ++-- lib/input/sketch/entities/layers/oval.dart | 4 ++-- lib/input/sketch/entities/layers/page.dart | 4 ++-- lib/input/sketch/entities/layers/polygon.dart | 4 ++-- .../sketch/entities/layers/rectangle.dart | 5 +++-- .../sketch/entities/layers/shape_group.dart | 4 ++-- .../sketch/entities/layers/shape_path.dart | 4 ++-- .../sketch/entities/layers/sketch_text.dart | 14 ++++++------- lib/input/sketch/entities/layers/star.dart | 4 ++-- .../entities/layers/symbol_instance.dart | 9 +++++---- .../sketch/entities/layers/symbol_master.dart | 8 ++++---- .../sketch/entities/layers/triangle.dart | 4 ++-- lib/input/sketch/entities/style/border.dart | 1 + .../sketch/entities/style/border_options.dart | 1 + lib/input/sketch/entities/style/color.dart | 2 ++ lib/input/sketch/entities/style/fill.dart | 1 + .../sketch/entities/style/shared_style.dart | 6 +++--- lib/input/sketch/entities/style/style.dart | 7 +++++-- .../sketch/entities/style/text_style.dart | 2 ++ lib/input/sketch/helper/sketch_project.dart | 2 +- lib/input/sketch/services/input_design.dart | 2 +- .../entities/alignments/flexible.dart | 3 +++ .../alignments/injected_positioned.dart | 2 ++ .../entities/alignments/padding.dart | 3 +++ .../entities/alignments/spacer.dart | 1 + .../entities/inherited_scaffold.dart | 2 ++ .../entities/layouts/rules/handle_flex.dart | 4 ++-- .../entities/layouts/stack.dart | 1 + .../layouts/temp_group_layout_node.dart | 6 +++--- .../pb_layout_intermediate_node.dart | 4 ++-- .../helpers/pb_gen_cache.dart | 14 ++++++------- .../helpers/pb_image_reference_storage.dart | 4 ++-- .../helpers/pb_plugin_list_helper.dart | 2 +- .../helpers/pb_symbol_storage.dart | 14 ++++++------- .../pb_shared_aggregation_service.dart | 2 +- lib/main.dart | 2 +- .../input_services/appbar_detection_test.dart | 2 +- .../input_services/input_to_pbdl_test.dart | 4 ++-- test/lib/layouts/layout_post_rules_test.dart | 2 +- .../dependency_writer_test.dart | 6 +++--- .../output_services/project_builder_test.dart | 2 +- 100 files changed, 256 insertions(+), 210 deletions(-) diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index 8ec7f291..663aae82 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -82,7 +82,7 @@ abstract class Controller { if (path.endsWith('/')) { return path; } else { - return '${path}/'; + return '$path/'; } } diff --git a/lib/controllers/design_controller.dart b/lib/controllers/design_controller.dart index f4936101..ba0e80e3 100644 --- a/lib/controllers/design_controller.dart +++ b/lib/controllers/design_controller.dart @@ -23,10 +23,10 @@ class DesignController extends Controller { }) async { configure(configurationPath, configType); - var designProject = await generateDesignProject(pbdf, outputPath); + var designProject = generateDesignProject(pbdf, outputPath); AzureAssetService().projectUUID = pbdf['id']; - await super.convertFile( + super.convertFile( pbdf, outputPath, configurationPath, diff --git a/lib/controllers/figma_controller.dart b/lib/controllers/figma_controller.dart index 301770dd..dfcba396 100644 --- a/lib/controllers/figma_controller.dart +++ b/lib/controllers/figma_controller.dart @@ -26,13 +26,13 @@ class FigmaController extends Controller { }) async { configure(configurationPath, configType); - var figmaProject = await generateFigmaTree(jsonFigma, outputPath); + var figmaProject = generateFigmaTree(jsonFigma, outputPath); figmaProject = declareScaffolds(figmaProject); _sortPages(figmaProject); - await super.convertFile( + super.convertFile( jsonFigma, outputPath, configurationPath, diff --git a/lib/controllers/sketch_controller.dart b/lib/controllers/sketch_controller.dart index db30f826..2e4f0d67 100644 --- a/lib/controllers/sketch_controller.dart +++ b/lib/controllers/sketch_controller.dart @@ -34,7 +34,7 @@ class SketchController extends Controller { AzureAssetService().projectUUID = sketchProject.id; - await super.convertFile( + super.convertFile( fileAbsPath, projectPath, configurationPath, diff --git a/lib/design_logic/artboard.dart b/lib/design_logic/artboard.dart index 17a15b00..075e5c58 100644 --- a/lib/design_logic/artboard.dart +++ b/lib/design_logic/artboard.dart @@ -63,6 +63,7 @@ class PBArtboard extends DesignNode implements GroupNode, DesignNodeFactory { @override DesignNode createDesignNode(Map json) => fromPBDF(json); + @override DesignNode fromPBDF(Map json) { var node = PBArtboard( backgroundColor: json['backgroundColor'] == null diff --git a/lib/design_logic/boolean_operation.dart b/lib/design_logic/boolean_operation.dart index f49d1787..9edbcc8f 100644 --- a/lib/design_logic/boolean_operation.dart +++ b/lib/design_logic/boolean_operation.dart @@ -24,7 +24,7 @@ class BooleanOperation implements DesignNodeFactory, DesignNode { type, Frame this.boundaryRectangle, String UUID, - String this.name, + this.name, bool isVisible, pbdfType, }); @@ -33,7 +33,7 @@ class BooleanOperation implements DesignNodeFactory, DesignNode { Future interpretNode(PBContext currentContext) async { var img = await AzureAssetService().downloadImage(UUID); var file = - File('${MainInfo().outputPath}pngs/${UUID}.png'.replaceAll(':', '_')) + File('${MainInfo().outputPath}pngs/$UUID.png'.replaceAll(':', '_')) ..createSync(recursive: true); file.writeAsBytesSync(img); diff --git a/lib/design_logic/image.dart b/lib/design_logic/image.dart index c3a43e62..87fca40f 100644 --- a/lib/design_logic/image.dart +++ b/lib/design_logic/image.dart @@ -96,7 +96,7 @@ class Image extends DesignElement implements DesignNodeFactory, DesignNode { try { var img = await AzureAssetService().downloadImage(UUID); var file = - File('${MainInfo().outputPath}pngs/${UUID}.png'.replaceAll(':', '_')) + File('${MainInfo().outputPath}pngs/$UUID.png'.replaceAll(':', '_')) ..createSync(recursive: true); file.writeAsBytesSync(img); return Future.value(InheritedBitmap( @@ -109,7 +109,7 @@ class Image extends DesignElement implements DesignNodeFactory, DesignNode { '${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png') .readAsBytesSync(); var file = - File('${MainInfo().outputPath}pngs/${UUID}.png'.replaceAll(':', '_')) + File('${MainInfo().outputPath}pngs/$UUID.png'.replaceAll(':', '_')) ..createSync(recursive: true); file.writeAsBytesSync(img); return Future.value(InheritedBitmap( diff --git a/lib/design_logic/oval.dart b/lib/design_logic/oval.dart index 0cb1c708..a85e6fc1 100644 --- a/lib/design_logic/oval.dart +++ b/lib/design_logic/oval.dart @@ -12,8 +12,10 @@ class Oval implements DesignNodeFactory, DesignNode { @override String pbdfType = 'oval'; + @override var boundaryRectangle; + @override var UUID; @override diff --git a/lib/design_logic/pb_shared_instance_design_node.dart b/lib/design_logic/pb_shared_instance_design_node.dart index 588a5ca0..3494b21a 100644 --- a/lib/design_logic/pb_shared_instance_design_node.dart +++ b/lib/design_logic/pb_shared_instance_design_node.dart @@ -111,8 +111,8 @@ class PBSharedInstanceDesignNode extends DesignNode ///Converting the [OverridableValue] into [PBSharedParameterValue] to be processed in intermediate phase. List _extractParameters() { - Set ovrNames = {}; - List sharedParameters = []; + var ovrNames = {}; + var sharedParameters = []; for (var overrideValue in overrideValues) { if (!ovrNames.contains(overrideValue.overrideName)) { var properties = extractParameter(overrideValue.overrideName); diff --git a/lib/design_logic/pb_shared_master_node.dart b/lib/design_logic/pb_shared_master_node.dart index 30949fe1..a6403b91 100644 --- a/lib/design_logic/pb_shared_master_node.dart +++ b/lib/design_logic/pb_shared_master_node.dart @@ -54,7 +54,7 @@ class PBSharedMasterDesignNode extends DesignNode maintainScrollPosition, bool includeBackgroundColorInExport, int changeIdentifier, - String this.symbolID, + this.symbolID, bool includeBackgroundColorInInstance, verticalRulerData, bool resizesContent, @@ -86,8 +86,8 @@ class PBSharedMasterDesignNode extends DesignNode ///Converting the [OverridableProperty] into [PBSharedParameterProp] to be processed in intermediate phase. List _extractParameters() { - Set ovrNames = {}; - List sharedParameters = []; + var ovrNames = {}; + var sharedParameters = []; for (var prop in overrideProperties) { if (!ovrNames.contains(prop.overrideName)) { var properties = AddMasterSymbolName(prop.overrideName, children); @@ -108,6 +108,7 @@ class PBSharedMasterDesignNode extends DesignNode @override DesignNode createDesignNode(Map json) => fromPBDF(json); + @override DesignNode fromPBDF(Map json) { var node = PBSharedMasterDesignNode( hasClickThrough: json['hasClickThrough'] as bool, diff --git a/lib/design_logic/polygon.dart b/lib/design_logic/polygon.dart index c3e81f12..a782649f 100644 --- a/lib/design_logic/polygon.dart +++ b/lib/design_logic/polygon.dart @@ -12,8 +12,10 @@ class Polygon implements DesignNodeFactory, DesignNode { @override String pbdfType = 'polygon'; + @override var boundaryRectangle; + @override var UUID; Polygon({ diff --git a/lib/design_logic/vector.dart b/lib/design_logic/vector.dart index a8c36d6e..e19e0755 100644 --- a/lib/design_logic/vector.dart +++ b/lib/design_logic/vector.dart @@ -56,6 +56,7 @@ class Vector implements DesignNodeFactory, DesignNode, Image { @override DesignNode createDesignNode(Map json) => fromPBDF(json); + @override DesignNode fromPBDF(Map json) { return Vector( name: json['name'] as String, @@ -106,7 +107,7 @@ class Vector implements DesignNodeFactory, DesignNode, Image { imageReference = AssetProcessingService.getImageName(UUID); var file = - File('${MainInfo().outputPath}pngs/${UUID}.png'.replaceAll(':', '_')) + File('${MainInfo().outputPath}pngs/$UUID.png'.replaceAll(':', '_')) ..createSync(recursive: true); file.writeAsBytesSync(img); return Future.value( diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index f1003b08..f03754ed 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -12,11 +12,13 @@ import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { + @override PBContext currentContext; @override String semanticName = ''; + @override String UUID; PBIntermediateNode get leadingItem => @@ -128,7 +130,7 @@ class PBAppBarGenerator extends PBGenerator { String _wrapOnIconButton(String body) { return ''' IconButton( - icon: ${body}, + icon: $body, onPressed: () { // TODO: Fill action } diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index b29767f9..95d9fbe4 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -14,8 +14,11 @@ import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'injected_tab.dart'; class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { + @override final String UUID; + @override PBContext currentContext; + @override String semanticName = ''; List get tabs => getAttributeNamed('tabs').attributeNodes; diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index 9e2c2379..78f1eb6a 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -40,7 +40,7 @@ class FlutterProjectBuilder { PBPageWriter pageWriter; FlutterProjectBuilder({this.projectName, this.mainTree, this.pageWriter}) { - pathToFlutterProject = '${projectName}/'; + pathToFlutterProject = '$projectName/'; generationConfiguration = configurations[MainInfo() .configurations['state-management'] .toString() diff --git a/lib/generation/generators/layouts/pb_row_gen.dart b/lib/generation/generators/layouts/pb_row_gen.dart index 4e0be6d3..67cbd8cd 100644 --- a/lib/generation/generators/layouts/pb_row_gen.dart +++ b/lib/generation/generators/layouts/pb_row_gen.dart @@ -12,7 +12,7 @@ class PBRowGenerator extends PBLayoutGenerator { if (source is PBIntermediateRowLayout) { var buffer = StringBuffer(); var counter = 0; - List children = source.children; + var children = source.children; for (var child in children) { child.currentContext = source.currentContext; diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 534e080e..8b7f481b 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -36,11 +36,11 @@ class BLoCMiddleware extends Middleware { addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - managerData.addToDispose('${globalVariableName}.close()'); + managerData.addToDispose('$globalVariableName.close()'); if (node.generator is! StringGeneratorAdapter) { node.generator = StringGeneratorAdapter(''' BlocBuilder<${generalStateName.pascalCase}Bloc, ${generalStateName.pascalCase}State>( - cubit: ${globalVariableName}, + cubit: $globalVariableName, builder: (context, state) => state.widget ) '''); @@ -54,12 +54,12 @@ class BLoCMiddleware extends Middleware { var stateBuffer = StringBuffer(); - await node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + node?.auxiliaryData?.stateGraph?.states?.forEach((state) { states.add(state.variation.node); }); var isFirst = true; - await states.forEach((element) { + states.forEach((element) { element.currentContext.tree.data = node.managerData; element.generator.templateStrategy = BLoCStateTemplateStrategy( isFirst: isFirst, @@ -72,14 +72,14 @@ class BLoCMiddleware extends Middleware { /// Creates state page await fileStrategy.generatePage( stateBuffer.toString(), - '${parentDirectory}/${generalName}_state', + '$parentDirectory/${generalName}_state', args: 'VIEW', ); /// Creates event page await fileStrategy.generatePage( _createEventPage(parentState), - '${parentDirectory}/${generalName}_event', + '$parentDirectory/${generalName}_event', args: 'VIEW', ); @@ -90,7 +90,7 @@ class BLoCMiddleware extends Middleware { parentState, node.name, ), - '${parentDirectory}/${generalName}_bloc', + '$parentDirectory/${generalName}_bloc', args: 'VIEW', ); diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 460d0325..cf638e3c 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -38,7 +38,7 @@ class ProviderMiddleware extends Middleware { if (node.currentContext.tree.rootNode.generator.templateStrategy is StatelessTemplateStrategy) { watcher = PBVariable(watcherName, 'final ', true, - '${getName(node.functionCallName).pascalCase}().${widgetName}'); + '${getName(node.functionCallName).pascalCase}().$widgetName'); managerData.addGlobalVariable(watcher); } @@ -52,21 +52,21 @@ class ProviderMiddleware extends Middleware { var providerWidget = ''' ChangeNotifierProvider( create: (context) => - ${modelName}(), + $modelName(), child: LayoutBuilder( builder: (context, constraints) { - var widget = ${defaultWidget}(constraints); + var widget = $defaultWidget(constraints); context - .read<${modelName}>() + .read<$modelName>() .setCurrentWidget( widget); // Setting active state return GestureDetector( onTap: () => context.read< - ${modelName}>(), // TODO: add your method to change the state here + $modelName>(), // TODO: add your method to change the state here child: context - .watch<${modelName}>() + .watch<$modelName>() .currentWidget, ); }, @@ -92,16 +92,16 @@ class ProviderMiddleware extends Middleware { // Generate default node's view page await fileStrategy.generatePage( - await generationManager.generate(node), - '${parentDirectory}/${node.name.snakeCase}', + generationManager.generate(node), + '$parentDirectory/${node.name.snakeCase}', args: 'VIEW', ); // Generate node's states' view pages node.auxiliaryData?.stateGraph?.states?.forEach((state) async { await fileStrategy.generatePage( - await generationManager.generate(state.variation.node), - '${parentDirectory}/${state.variation.node.name.snakeCase}', + generationManager.generate(state.variation.node), + '$parentDirectory/${state.variation.node.name.snakeCase}', args: 'VIEW', ); }); diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 7c3f298d..8984811e 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -63,8 +63,8 @@ class RiverpodMiddleware extends Middleware { return ''' Consumer( builder: (context, watch, child) { - final ${name} = watch(${name}_provider); - return ${name}.${pointTo}; + final $name = watch(${name}_provider); + return $name.$pointTo; }, ) '''; diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index a1f7d607..ab7aa726 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -22,15 +22,15 @@ class StatefulMiddleware extends Middleware { var states = [node]; var parentDirectory = getName(node.name).snakeCase; - await node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + node?.auxiliaryData?.stateGraph?.states?.forEach((state) { states.add(state.variation.node); }); - await states.forEach((element) async { + states.forEach((element) async { element.currentContext.tree.data = node.managerData; await fileStrategy.generatePage( - await generationManager.generate(element), - '${parentDirectory}/${element.name.snakeCase}', + generationManager.generate(element), + '$parentDirectory/${element.name.snakeCase}', args: 'VIEW', ); }); diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 767e49c2..a74d0c38 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -47,14 +47,14 @@ class MiddlewareUtils { return ''' ${manager.generateImports()} - class ${defaultStateName} extends ChangeNotifier { + class $defaultStateName extends ChangeNotifier { ${stateBuffer.toString()} - ${overrideVars} + $overrideVars Widget defaultWidget; - ${defaultStateName}(${overrideAttr.isNotEmpty ? ('\{' + overrideAttr + '\}') : ''}){ + $defaultStateName(${overrideAttr.isNotEmpty ? ('\{' + overrideAttr + '\}') : ''}){ - ${stateInitializers} + $stateInitializers defaultWidget = ${node.name.camelCase}; } @@ -73,10 +73,10 @@ class MiddlewareUtils { }); return ''' ${manager.generateImports()} - class ${defaultStateName} extends ChangeNotifier { + class $defaultStateName extends ChangeNotifier { Widget currentWidget; - ${defaultStateName}(){} + $defaultStateName(){} void setCurrentWidget(Widget currentWidget) { this.currentWidget = currentWidget; @@ -87,12 +87,12 @@ class MiddlewareUtils { static String generateVariable(PBIntermediateNode node, {String type = 'var'}) { - return '${type} ${node.name.camelCase} = ' + generateVariableBody(node); + return '$type ${node.name.camelCase} = ' + generateVariableBody(node); } static String generateEmptyVariable(PBIntermediateNode node, {String type = 'var'}) => - '${type} ${node.name.camelCase};'; + '$type ${node.name.camelCase};'; static String generateVariableBody(node) => (node?.generator?.generate(node ?? '', diff --git a/lib/generation/generators/pb_flutter_generator.dart b/lib/generation/generators/pb_flutter_generator.dart index f771c87e..7f04b3f4 100644 --- a/lib/generation/generators/pb_flutter_generator.dart +++ b/lib/generation/generators/pb_flutter_generator.dart @@ -81,6 +81,7 @@ class PBFlutterGenerator extends PBGenerationManager { } /// Generates the dispose method + @override String generateDispose() { var buffer = StringBuffer(); var it = data.toDispose; @@ -105,7 +106,7 @@ class PBFlutterGenerator extends PBGenerationManager { } rootNode.generator.manager = this; if (rootNode.generator == null) { - log.error('Generator not registered for ${rootNode}'); + log.error('Generator not registered for $rootNode'); } return rootNode.generator?.templateStrategy?.generateTemplate( rootNode, diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index a49a3614..15c402bd 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -8,6 +8,7 @@ abstract class PBEgg extends PBVisualIntermediateNode { /// The allow list semantic name to detect this node. String semanticName; + @override final String UUID; PBEgg(Point topLeftCorner, Point bottomRightCorner, PBContext currentContext, @@ -25,5 +26,6 @@ abstract class PBEgg extends PBVisualIntermediateNode { void extractInformation(DesignNode incomingNode); + @override void addChild(PBIntermediateNode node); } diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 0113a7ae..8424e508 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -40,7 +40,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { buffer.write(' return '); if (overrideProp != null) { - buffer.write('${overrideProp} ?? '); + buffer.write('$overrideProp ?? '); } buffer.write(method_signature); @@ -50,7 +50,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { for (var param in source.sharedParamValues ?? []) { switch (param.type) { case PBSharedInstanceIntermediateNode: - String siString = genSymbolInstance( + var siString = genSymbolInstance( param.UUID, param.value, source.overrideValues); if (siString != '') { buffer.write('${param.name}: '); @@ -108,7 +108,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { } assert(masterSymbol != null, - 'Could not find master symbol with UUID: ${UUID}'); + 'Could not find master symbol with UUID: $UUID'); var buffer = StringBuffer(); buffer.write('${masterSymbol.friendlyName}(constraints, '); for (var ovrValue in overrideValues) { @@ -124,16 +124,16 @@ class PBSymbolInstanceGenerator extends PBGenerator { break; case InheritedBitmap: var name = SN_UUIDtoVarName[ovrUUID + '_image']; - buffer.write('${name}: \"assets/${ovrValue.value["_ref"]}\",'); + buffer.write('$name: \"assets/${ovrValue.value["_ref"]}\",'); break; case TextStyle: var name = SN_UUIDtoVarName[ovrUUID + '_textStyle']; buffer.write( - '${name}: ${SharedStyle_UUIDToName[ovrValue.value] ?? "TextStyle()"},'); + '$name: ${SharedStyle_UUIDToName[ovrValue.value] ?? "TextStyle()"},'); break; default: var name = SN_UUIDtoVarName[ovrUUID]; - buffer.write('${name}: \"${ovrValue.value}\",'); + buffer.write('$name: \"${ovrValue.value}\",'); break; } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 6058e0e1..809d6c01 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -70,8 +70,8 @@ abstract class FileStructureStrategy implements CommandInvoker { ///[RELATIVE_VIEW_PATH] and [RELATIVE_SCREEN_PATH]. Future setUpDirectories() async { if (!isSetUp) { - _screenDirectoryPath = '${GENERATED_PROJECT_PATH}${RELATIVE_SCREEN_PATH}'; - _viewDirectoryPath = '${GENERATED_PROJECT_PATH}${RELATIVE_VIEW_PATH}'; + _screenDirectoryPath = '$GENERATED_PROJECT_PATH$RELATIVE_SCREEN_PATH'; + _viewDirectoryPath = '$GENERATED_PROJECT_PATH$RELATIVE_VIEW_PATH'; _pbProject.forest.forEach((dir) { if (dir.rootNode != null) { addImportsInfo(dir); @@ -92,11 +92,11 @@ abstract class FileStructureStrategy implements CommandInvoker { if (name != null) { var uuid = node is PBSharedMasterNode ? node.SYMBOL_ID : node.UUID; var path = node is PBSharedMasterNode - ? '${_viewDirectoryPath}${tree.name.snakeCase}/${name}.dart' // Removed .g - : '${_screenDirectoryPath}${tree.name.snakeCase}/${name}.dart'; + ? '$_viewDirectoryPath${tree.name.snakeCase}/$name.dart' // Removed .g + : '$_screenDirectoryPath${tree.name.snakeCase}/$name.dart'; if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { path = - '${_screenDirectoryPath}$name/${poLinker.stripPlatform(tree.rootNode.managerData.platform)}/$name.dart'; + '$_screenDirectoryPath$name/${poLinker.stripPlatform(tree.rootNode.managerData.platform)}/$name.dart'; } PBGenCache().setPathToCache(uuid, path); } else { @@ -112,15 +112,15 @@ abstract class FileStructureStrategy implements CommandInvoker { Future generatePage(String code, String fileName, {var args}) { if (args is String) { var path = args == 'SCREEN' - ? '${_screenDirectoryPath}${fileName}.dart' - : '${_viewDirectoryPath}${fileName}.dart'; // Removed .g + ? '$_screenDirectoryPath$fileName.dart' + : '$_viewDirectoryPath$fileName.dart'; // Removed .g pageWriter.write(code, path); } return Future.value(); } String getViewPath(String fileName) => - '${_viewDirectoryPath}${fileName}.dart'; + '$_viewDirectoryPath$fileName.dart'; @override void commandCreated(FileStructureCommand command) { diff --git a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart index da402f5c..af85f667 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart @@ -13,8 +13,8 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { ProviderFileStructureStrategy( String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) : super(genProjectPath, pageWriter, pbProject) { - _providersPath = '${genProjectPath}${RELATIVE_PROVIDER_PATH}'; - _modelsPath = '${genProjectPath}${RELATIVE_MODEL_PATH}'; + _providersPath = '$genProjectPath$RELATIVE_PROVIDER_PATH'; + _modelsPath = '$genProjectPath$RELATIVE_MODEL_PATH'; } @override @@ -34,6 +34,6 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { void writeProviderModelFile(String code, String fileName) { super .pageWriter - .write(code, '${_modelsPath}${fileName}.dart'); // Removed .g + .write(code, '$_modelsPath$fileName.dart'); // Removed .g } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart index 8620d23a..855eb39b 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart @@ -13,8 +13,8 @@ class RiverpodFileStructureStrategy extends FileStructureStrategy { RiverpodFileStructureStrategy( String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) : super(genProjectPath, pageWriter, pbProject) { - _providersPath = '${genProjectPath}${RELATIVE_PROVIDER_PATH}'; - _modelsPath = '${genProjectPath}${RELATIVE_MODEL_PATH}'; + _providersPath = '$genProjectPath$RELATIVE_PROVIDER_PATH'; + _modelsPath = '$genProjectPath$RELATIVE_MODEL_PATH'; } @override @@ -34,6 +34,6 @@ class RiverpodFileStructureStrategy extends FileStructureStrategy { void writeRiverpodModelFile(String code, String fileName) { super .pageWriter - .write(code, '${_modelsPath}${fileName}.dart'); // Removed .g + .write(code, '$_modelsPath$fileName.dart'); // Removed .g } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 973ab79e..8c4bba07 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -127,11 +127,11 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { var platformFolder = poLinker.stripPlatform(tree.rootNode.managerData.platform); - relPath = '${fileName}/$platformFolder/$fileName'; + relPath = '$fileName/$platformFolder/$fileName'; } if (tree.rootNode is InheritedScaffold && (tree.rootNode as InheritedScaffold).isHomeScreen) { - await _setMainScreen(tree.rootNode, '$relPath.dart'); + _setMainScreen(tree.rootNode, '$relPath.dart'); } await _iterateNode(tree.rootNode); @@ -143,20 +143,20 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { tree.rootNode.currentContext.tree.data.platform, '$fileName', '$fileName${getPlatformOrientationName(tree.rootNode)}.dart', - await _generationManager.generate(tree.rootNode), + _generationManager.generate(tree.rootNode), )); } else if (tree.rootNode is InheritedScaffold) { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(WriteScreenCommand( '$fileName.dart', '${tree.name}', - await _generationManager.generate(tree.rootNode), + _generationManager.generate(tree.rootNode), )); } else { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(WriteSymbolCommand( '$fileName.dart', - await _generationManager.generate(tree.rootNode), + _generationManager.generate(tree.rootNode), )); } } @@ -209,7 +209,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await writer.writeMainScreenWithHome( node.name, fileStructureStrategy.GENERATED_PROJECT_PATH + 'lib/main.dart', - 'screens/${outputMain}'); + 'screens/$outputMain'); } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index f9b98725..1a7f6ca2 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -53,7 +53,7 @@ mixin PBPlatformOrientationGeneration { Map> platformsMap, String className) { var result = ''; platformsMap.forEach((platform, value) { - result += '${platform}Widget: ${className}_${platform}(),'; + result += '${platform}Widget: ${className}_$platform(),'; }); return result; } @@ -81,11 +81,6 @@ mixin PBPlatformOrientationGeneration { var map = PBPlatformOrientationLinkerService() .getPlatformOrientationData(node.name); - // if (map.length > 1) { - // var platform = PBPlatformOrientationLinkerService() - // .stripPlatform(node.currentContext.treeRoot.data.platform); - // result += '_$platform'; - // } if (map[node.currentContext.tree.data.platform].length > 1) { var orientation = PBPlatformOrientationLinkerService() .stripOrientation(node.currentContext.tree.data.orientation); diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index 9a46fd47..a5cb626c 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -30,13 +30,13 @@ ${isFirst ? _getHeader(manager) : ''} class ${node.name.pascalCase}State extends ${abstractClassName.pascalCase}State{ ${manager.generateGlobalVariables()} - ${overrideVars} + $overrideVars ${widgetName + 'State'}(${(overrides.isNotEmpty ? '{$overrides}' : '')}){} @override - Widget get widget => ${returnStatement}; + Widget get widget => $returnStatement; }'''; } diff --git a/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart index 626e482f..0b329d51 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart @@ -15,20 +15,20 @@ class StatefulTemplateStrategy extends TemplateStrategy { return ''' ${manager.generateImports()} -class ${widgetName} extends StatefulWidget{ - const ${widgetName}() : super(); +class $widgetName extends StatefulWidget{ + const $widgetName() : super(); @override - _${widgetName} createState() => _${widgetName}(); + _$widgetName createState() => _$widgetName(); } -class _${widgetName} extends State<${widgetName}>{ +class _$widgetName extends State<$widgetName>{ ${manager.generateGlobalVariables()} _${manager.generateConstructor(constructorName)} @override Widget build(BuildContext context){ ${manager.data.methodVariableStr} - return ${returnStatement}; + return $returnStatement; } ${manager.generateDispose()} diff --git a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart index 6e39d7cc..04217c1c 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart @@ -31,7 +31,7 @@ class ${widgetName.pascalCase} extends StatelessWidget{ @override Widget build(BuildContext context){ - return ${returnStatement}; + return $returnStatement; } }'''; } diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index 6036da4d..c577c405 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -70,7 +70,7 @@ class MyApp extends StatelessWidget { primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), - home: ${homeName}(), + home: $homeName(), ); } }'''); @@ -86,8 +86,8 @@ class MyApp extends StatelessWidget { line = readYaml.indexOf('dependencies:'); if (line > 0) { dependencies.forEach((packageName, version) { - if (!readYaml.contains(' ${packageName}: ${version}')) { - readYaml.insert(++line, ' ${packageName}: ${version}'); + if (!readYaml.contains(' $packageName: $version')) { + readYaml.insert(++line, ' $packageName: $version'); } }); diff --git a/lib/generation/prototyping/pb_prototype_gen.dart b/lib/generation/prototyping/pb_prototype_gen.dart index 63246a23..dc7bb764 100644 --- a/lib/generation/prototyping/pb_prototype_gen.dart +++ b/lib/generation/prototyping/pb_prototype_gen.dart @@ -21,7 +21,7 @@ class PBPrototypeGenerator extends PBGenerator { onTap: () { Navigator.push( context, - MaterialPageRoute(builder: (context) => ${name}()), + MaterialPageRoute(builder: (context) => $name()), ); }, child: ${source.child.generator.generate(source.child, generatorContext)}, diff --git a/lib/generation/prototyping/pb_prototype_linker_service.dart b/lib/generation/prototyping/pb_prototype_linker_service.dart index b895b8fa..f5898c53 100644 --- a/lib/generation/prototyping/pb_prototype_linker_service.dart +++ b/lib/generation/prototyping/pb_prototype_linker_service.dart @@ -50,19 +50,19 @@ class PBPrototypeLinkerService { .prototypeNode .destinationUUID .isNotEmpty) { - await addAndPopulatePrototypeNode(currentNode, rootNode); + addAndPopulatePrototypeNode(currentNode, rootNode); } else if (currentNode is PBLayoutIntermediateNode && currentNode.prototypeNode?.destinationUUID != null && currentNode.prototypeNode.destinationUUID.isNotEmpty) { - await addAndPopulatePrototypeNode(currentNode, rootNode); + addAndPopulatePrototypeNode(currentNode, rootNode); } else if (currentNode is InjectedContainer && currentNode.prototypeNode?.destinationUUID != null && currentNode.prototypeNode.destinationUUID.isNotEmpty) { - await addAndPopulatePrototypeNode(currentNode, rootNode); + addAndPopulatePrototypeNode(currentNode, rootNode); } else if (currentNode is Tab && currentNode.prototypeNode?.destinationUUID != null && currentNode.prototypeNode.destinationUUID.isNotEmpty) { - await addAndPopulatePrototypeNode(currentNode, rootNode); + addAndPopulatePrototypeNode(currentNode, rootNode); } } return rootNode; diff --git a/lib/generation/prototyping/pb_prototype_storage.dart b/lib/generation/prototyping/pb_prototype_storage.dart index d5f14e83..1dbe93bc 100644 --- a/lib/generation/prototyping/pb_prototype_storage.dart +++ b/lib/generation/prototyping/pb_prototype_storage.dart @@ -29,7 +29,7 @@ class PBPrototypeStorage { return false; } - await PBPrototypeAggregationService() + PBPrototypeAggregationService() .analyzeIntermediateNode(prototypeNode); _pbPrototypeInstanceNodes['${prototypeNode.UUID}'] = prototypeNode; return true; diff --git a/lib/input/figma/entities/layers/boolean_operation.dart b/lib/input/figma/entities/layers/boolean_operation.dart index 190248f6..36a6844a 100644 --- a/lib/input/figma/entities/layers/boolean_operation.dart +++ b/lib/input/figma/entities/layers/boolean_operation.dart @@ -17,6 +17,7 @@ part 'boolean_operation.g.dart'; @JsonSerializable(nullable: true) class BooleanOperation extends FigmaVector implements FigmaNodeFactory, GroupNode, Image { + @override @JsonKey(ignore: true) Logger log; @override diff --git a/lib/input/figma/entities/layers/canvas.dart b/lib/input/figma/entities/layers/canvas.dart index 81bd7e62..f57c5fae 100644 --- a/lib/input/figma/entities/layers/canvas.dart +++ b/lib/input/figma/entities/layers/canvas.dart @@ -56,6 +56,7 @@ class Canvas extends FigmaNode implements FigmaNodeFactory, GroupNode { Canvas createSketchNode(Map json) => Canvas.fromJson(json); factory Canvas.fromJson(Map json) => _$CanvasFromJson(json); + @override Map toJson() => _$CanvasToJson(this); @override diff --git a/lib/input/figma/entities/layers/component.dart b/lib/input/figma/entities/layers/component.dart index c751ccb8..345f6218 100644 --- a/lib/input/figma/entities/layers/component.dart +++ b/lib/input/figma/entities/layers/component.dart @@ -88,8 +88,8 @@ class Component extends FigmaFrame Map toJson() => _$ComponentToJson(this); List _extractParameters() { - Set ovrNames = {}; - List sharedParameters = []; + var ovrNames = {}; + var sharedParameters = []; overrideProperties ??= []; for (var prop in overrideProperties) { if (!ovrNames.contains(prop.overrideName)) { diff --git a/lib/input/figma/entities/layers/ellipse.dart b/lib/input/figma/entities/layers/ellipse.dart index d8c8b5a6..7afe254b 100644 --- a/lib/input/figma/entities/layers/ellipse.dart +++ b/lib/input/figma/entities/layers/ellipse.dart @@ -18,6 +18,7 @@ class FigmaEllipse extends FigmaVector implements AbstractFigmaNodeFactory, Image { @override String imageReference; + @override @JsonKey(ignore: true) Logger log; diff --git a/lib/input/figma/entities/layers/figma_paragraph_style.dart b/lib/input/figma/entities/layers/figma_paragraph_style.dart index 70189b7e..1a15584a 100644 --- a/lib/input/figma/entities/layers/figma_paragraph_style.dart +++ b/lib/input/figma/entities/layers/figma_paragraph_style.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/design_logic/pb_paragraph_style.dart'; class FigmaParagraphStyle implements PBParagraphStyle { + @override int alignment = ALIGNMENT.LEFT.index; FigmaParagraphStyle({this.alignment}); diff --git a/lib/input/figma/entities/layers/group.dart b/lib/input/figma/entities/layers/group.dart index 8723bab1..3b0c398b 100644 --- a/lib/input/figma/entities/layers/group.dart +++ b/lib/input/figma/entities/layers/group.dart @@ -103,7 +103,7 @@ class Group extends FigmaFrame implements AbstractFigmaNodeFactory, Image { var tempPrototypeID = childrenHavePrototypeNode(); if (tempPrototypeID != null) { - this.prototypeNodeUUID = tempPrototypeID; + prototypeNodeUUID = tempPrototypeID; } if (children != null && children.isNotEmpty) { diff --git a/lib/input/figma/entities/style/figma_border.dart b/lib/input/figma/entities/style/figma_border.dart index 9f748971..fd6f11a1 100644 --- a/lib/input/figma/entities/style/figma_border.dart +++ b/lib/input/figma/entities/style/figma_border.dart @@ -23,6 +23,7 @@ class FigmaBorder implements PBBorder { this.thickness, }); + @override Map toJson() => _$FigmaBorderToJson(this); factory FigmaBorder.fromJson(Map json) => _$FigmaBorderFromJson(json); diff --git a/lib/input/figma/entities/style/figma_border_options.dart b/lib/input/figma/entities/style/figma_border_options.dart index 34776b1c..a2526098 100644 --- a/lib/input/figma/entities/style/figma_border_options.dart +++ b/lib/input/figma/entities/style/figma_border_options.dart @@ -26,6 +26,7 @@ class FigmaBorderOptions implements PBBorderOptions { this.lineJoinStyle, ); + @override Map toJson() => _$FigmaBorderOptionsToJson(this); factory FigmaBorderOptions.fromJson(Map json) => diff --git a/lib/input/figma/entities/style/figma_fill.dart b/lib/input/figma/entities/style/figma_fill.dart index 1ef4bd81..814fcfb4 100644 --- a/lib/input/figma/entities/style/figma_fill.dart +++ b/lib/input/figma/entities/style/figma_fill.dart @@ -14,6 +14,7 @@ class FigmaFill implements PBFill { @override bool isEnabled; + @override Map toJson() => _$FigmaFillToJson(this); factory FigmaFill.fromJson(Map json) => _$FigmaFillFromJson(json); diff --git a/lib/input/figma/entities/style/figma_style.dart b/lib/input/figma/entities/style/figma_style.dart index 316f715e..7b820a9a 100644 --- a/lib/input/figma/entities/style/figma_style.dart +++ b/lib/input/figma/entities/style/figma_style.dart @@ -31,14 +31,15 @@ class FigmaStyle implements PBStyle { FigmaTextStyle this.textStyle, FigmaBorderOptions this.borderOptions, }) { - if (this.fills == null) { - this.fills = []; + if (fills == null) { + fills = []; } } @override PBBorderOptions borderOptions; + @override Map toJson() => _$FigmaStyleToJson(this); factory FigmaStyle.fromJson(Map json) => _$FigmaStyleFromJson(json); diff --git a/lib/input/figma/entities/style/figma_text_style.dart b/lib/input/figma/entities/style/figma_text_style.dart index cc3c4760..ceb567dc 100644 --- a/lib/input/figma/entities/style/figma_text_style.dart +++ b/lib/input/figma/entities/style/figma_text_style.dart @@ -32,6 +32,7 @@ class FigmaTextStyle implements PBTextStyle { this.paragraphStyle, }); + @override Map toJson() => _$FigmaTextStyleToJson(this); factory FigmaTextStyle.fromJson(Map json) => _$FigmaTextStyleFromJson(json); diff --git a/lib/input/figma/helper/api_call_service.dart b/lib/input/figma/helper/api_call_service.dart index 6248856b..f820b6a6 100644 --- a/lib/input/figma/helper/api_call_service.dart +++ b/lib/input/figma/helper/api_call_service.dart @@ -72,20 +72,20 @@ class APICallService { // log.debug('API call went successfully : ${status}'); break; case 400: - log.error('BadRequestException : ${status}'); + log.error('BadRequestException : $status'); throw BadRequestException(); break; case 401: case 403: - log.error('UnauthorizedException : ${status}'); + log.error('UnauthorizedException : $status'); throw UnauthorisedException(); break; case 500: default: log.error( - 'Error occured while Communication with Server with StatusCode : ${status}'); + 'Error occured while Communication with Server with StatusCode : $status'); throw FetchDataException( - 'Error occured while Communication with Server with StatusCode : ${status}'); + 'Error occured while Communication with Server with StatusCode : $status'); break; } } diff --git a/lib/input/figma/helper/api_exceptions.dart b/lib/input/figma/helper/api_exceptions.dart index 1f00fc15..c6e69347 100644 --- a/lib/input/figma/helper/api_exceptions.dart +++ b/lib/input/figma/helper/api_exceptions.dart @@ -2,6 +2,7 @@ class APIException implements Exception { final _message; final _prefix; APIException([this._message, this._prefix]); + @override String toString() { return "$_prefix$_message"; } @@ -9,17 +10,17 @@ class APIException implements Exception { class FetchDataException extends APIException { FetchDataException([String message]) - : super(message, "Error During Communication: "); + : super(message, 'Error During Communication: '); } class BadRequestException extends APIException { - BadRequestException([message]) : super(message, "Invalid Request: "); + BadRequestException([message]) : super(message, 'Invalid Request: '); } class UnauthorisedException extends APIException { - UnauthorisedException([message]) : super(message, "Unauthorised: "); + UnauthorisedException([message]) : super(message, 'Unauthorised: '); } class InvalidInputException extends APIException { - InvalidInputException([String message]) : super(message, "Invalid Input: "); + InvalidInputException([String message]) : super(message, 'Invalid Input: '); } diff --git a/lib/input/figma/helper/style_extractor.dart b/lib/input/figma/helper/style_extractor.dart index 2eded750..463a3b07 100644 --- a/lib/input/figma/helper/style_extractor.dart +++ b/lib/input/figma/helper/style_extractor.dart @@ -34,7 +34,7 @@ class StyleExtractor { textStyle = _getTextStyle(json); } - List borders = []; + var borders = []; var strokes = json['strokes']; @@ -62,7 +62,7 @@ class StyleExtractor { borders.add(figmaBorder); - List fills = []; + var fills = []; var fill = FigmaFill( _getColor(json['fills'].isNotEmpty ? json['fills'][0]['color'] : null), diff --git a/lib/input/helper/asset_processing_service.dart b/lib/input/helper/asset_processing_service.dart index b8d7420a..e121c01a 100644 --- a/lib/input/helper/asset_processing_service.dart +++ b/lib/input/helper/asset_processing_service.dart @@ -24,7 +24,7 @@ abstract class AssetProcessingService { ); var blob = await aaService.putBlob( aaService.projectUUID, - '${name}.png', + '$name.png', img, ); await cont.stream.drain(); diff --git a/lib/input/helper/azure_asset_service.dart b/lib/input/helper/azure_asset_service.dart index 805bde33..6a8c3d17 100644 --- a/lib/input/helper/azure_asset_service.dart +++ b/lib/input/helper/azure_asset_service.dart @@ -19,7 +19,7 @@ class AzureAssetService { static const KEY_NAME = 'STORAGE_CONNECTION_STRING'; - String getImageURI(String imageName) => getContainerUri() + '/${imageName}'; + String getImageURI(String imageName) => getContainerUri() + '/$imageName'; String getContainerUri() { if (Platform.environment.containsKey(KEY_NAME) && projectUUID != null) { @@ -27,7 +27,7 @@ class AzureAssetService { var protocol = storageStringList[0].split('=')[1]; var accName = storageStringList[1].split('=')[1]; var suffix = storageStringList.last.split('=')[1]; - return '${protocol}://${accName}.blob.${suffix}/${projectUUID}'; + return '$protocol://$accName.blob.$suffix/$projectUUID'; } return ''; } @@ -39,10 +39,10 @@ class AzureAssetService { var uri, headers; // Request if (queryParams == null) { - uri = storage.uri(path: '${path}'); + uri = storage.uri(path: '$path'); headers = {'x-ms-blob-type': 'BlockBlob'}; } else { - uri = storage.uri(path: '${path}', queryParameters: queryParams); + uri = storage.uri(path: '$path', queryParameters: queryParams); } var request = http.Request('PUT', uri); @@ -58,16 +58,16 @@ class AzureAssetService { Future createContainer( String container, Uint8List bodyBytes) async => - await _putRequestBlob('/${container}', bodyBytes, + await _putRequestBlob('/$container', bodyBytes, queryParams: {'restype': 'container'}); Future putBlob( String container, String filename, Uint8List bodyBytes) async => - await _putRequestBlob('/${container}/${filename}', bodyBytes); + await _putRequestBlob('/$container/$filename', bodyBytes); Future downloadImage(String uuid) async { var storage = AzureStorage.parse(Platform.environment[KEY_NAME]); - var uri = storage.uri(path: '/${projectUUID}/${uuid}.png'); + var uri = storage.uri(path: '/$projectUUID/$uuid.png'); var request = http.Request('GET', uri); storage.sign(request); diff --git a/lib/input/helper/design_page.dart b/lib/input/helper/design_page.dart index bc87c9be..86e6d848 100644 --- a/lib/input/helper/design_page.dart +++ b/lib/input/helper/design_page.dart @@ -30,13 +30,13 @@ class DesignPage implements DesignNodeFactory { /// Parabeac Design File Map toPBDF() { - Map result = {}; + var result = {}; result['pbdfType'] = pbdfType; result['id'] = id; result['name'] = name; result['convert'] = convert; - List tempScreens = []; + var tempScreens = []; for (var screen in screens) { tempScreens.add(screen.toPBDF()); } diff --git a/lib/input/helper/design_project.dart b/lib/input/helper/design_project.dart index afcac937..03d17f0f 100644 --- a/lib/input/helper/design_project.dart +++ b/lib/input/helper/design_project.dart @@ -28,8 +28,8 @@ class DesignProject implements DesignNodeFactory { result['pbdfType'] = pbdfType; result['id'] = id; - List tmpPages = []; - List tmpMiscPages = []; + var tmpPages = []; + var tmpMiscPages = []; for (var page in pages) { tmpPages.add(page.toPBDF()); } diff --git a/lib/input/helper/design_screen.dart b/lib/input/helper/design_screen.dart index 26bc988a..050350bc 100644 --- a/lib/input/helper/design_screen.dart +++ b/lib/input/helper/design_screen.dart @@ -23,7 +23,7 @@ class DesignScreen implements DesignNodeFactory { Map toPBDF() { var result = {}; - if (this.type == 'symbolMaster') { + if (type == 'symbolMaster') { result['pbdfType'] = 'symbol_master'; } else { result['pbdfType'] = pbdfType; diff --git a/lib/input/sketch/entities/layers/abstract_group_layer.dart b/lib/input/sketch/entities/layers/abstract_group_layer.dart index 45ae83f1..29902209 100644 --- a/lib/input/sketch/entities/layers/abstract_group_layer.dart +++ b/lib/input/sketch/entities/layers/abstract_group_layer.dart @@ -67,7 +67,7 @@ abstract class AbstractGroupLayer extends SketchNode implements GroupNode { Map toJson(); List getChildren() { - List result = []; + var result = []; for (var child in children) { result.add((child as DesignNode).toPBDF()); } diff --git a/lib/input/sketch/entities/layers/abstract_layer.dart b/lib/input/sketch/entities/layers/abstract_layer.dart index 92a6dc72..22077cf8 100644 --- a/lib/input/sketch/entities/layers/abstract_layer.dart +++ b/lib/input/sketch/entities/layers/abstract_layer.dart @@ -27,8 +27,10 @@ abstract class SketchNode implements DesignNode { final bool isFlippedHorizontal; final bool isFlippedVertical; final bool isLocked; + @override final bool isVisible; final dynamic layerListExpandedType; + @override String name; final bool nameIsFixed; final dynamic resizingConstraint; @@ -39,6 +41,7 @@ abstract class SketchNode implements DesignNode { final bool hasClippingMask; final int clippingMaskMode; final dynamic userInfo; + @override final Style style; final bool maintainScrollPosition; @@ -52,7 +55,7 @@ abstract class SketchNode implements DesignNode { this.booleanOperation, this.exportOptions, Frame this.boundaryRectangle, - Flow this.flow, + this.flow, this.isFixedToViewport, this.isFlippedHorizontal, this.isFlippedVertical, diff --git a/lib/input/sketch/entities/layers/artboard.dart b/lib/input/sketch/entities/layers/artboard.dart index cae7d35b..3e1e9106 100644 --- a/lib/input/sketch/entities/layers/artboard.dart +++ b/lib/input/sketch/entities/layers/artboard.dart @@ -45,6 +45,7 @@ class Artboard extends AbstractGroupLayer String UUID; final bool hasBackgroundColor; + @override final bool isFlowHome; final bool resizesContent; final dynamic presetDictionary; @@ -54,13 +55,13 @@ class Artboard extends AbstractGroupLayer Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; @@ -214,7 +215,7 @@ class Artboard extends AbstractGroupLayer } @override - void set isFlowHome(_isFlowHome) { + set isFlowHome(_isFlowHome) { // TODO: implement isFlowHome } } diff --git a/lib/input/sketch/entities/layers/bitmap.dart b/lib/input/sketch/entities/layers/bitmap.dart index d0d483d2..7e3333d1 100644 --- a/lib/input/sketch/entities/layers/bitmap.dart +++ b/lib/input/sketch/entities/layers/bitmap.dart @@ -130,13 +130,13 @@ class Bitmap extends SketchNode implements SketchNodeFactory, Image { Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/layers/group.dart b/lib/input/sketch/entities/layers/group.dart index 32338b7e..aa5bf2a1 100644 --- a/lib/input/sketch/entities/layers/group.dart +++ b/lib/input/sketch/entities/layers/group.dart @@ -37,13 +37,13 @@ class Group extends AbstractGroupLayer implements SketchNodeFactory { Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/layers/oval.dart b/lib/input/sketch/entities/layers/oval.dart index 4f741722..37931bbc 100644 --- a/lib/input/sketch/entities/layers/oval.dart +++ b/lib/input/sketch/entities/layers/oval.dart @@ -35,13 +35,13 @@ class Oval extends AbstractShapeLayer implements SketchNodeFactory { Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/layers/page.dart b/lib/input/sketch/entities/layers/page.dart index 10e14c16..3df29920 100644 --- a/lib/input/sketch/entities/layers/page.dart +++ b/lib/input/sketch/entities/layers/page.dart @@ -45,13 +45,13 @@ class Page extends AbstractGroupLayer implements SketchNodeFactory { List children; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/layers/polygon.dart b/lib/input/sketch/entities/layers/polygon.dart index 800b0fa9..4f37ea68 100644 --- a/lib/input/sketch/entities/layers/polygon.dart +++ b/lib/input/sketch/entities/layers/polygon.dart @@ -36,13 +36,13 @@ class Polygon extends AbstractShapeLayer implements SketchNodeFactory { Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/layers/rectangle.dart b/lib/input/sketch/entities/layers/rectangle.dart index 573789e4..18beda16 100644 --- a/lib/input/sketch/entities/layers/rectangle.dart +++ b/lib/input/sketch/entities/layers/rectangle.dart @@ -26,6 +26,7 @@ class Rectangle extends AbstractShapeLayer final double fixedRadius; final bool hasConvertedToNewRoundCorners; final bool needsConvertionToNewRoundCorners; + @override @JsonKey(name: 'frame') var boundaryRectangle; @override @@ -41,13 +42,13 @@ class Rectangle extends AbstractShapeLayer Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/layers/shape_group.dart b/lib/input/sketch/entities/layers/shape_group.dart index 4bf41bc8..bec2755e 100644 --- a/lib/input/sketch/entities/layers/shape_group.dart +++ b/lib/input/sketch/entities/layers/shape_group.dart @@ -37,13 +37,13 @@ class ShapeGroup extends AbstractGroupLayer implements SketchNodeFactory { Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/layers/shape_path.dart b/lib/input/sketch/entities/layers/shape_path.dart index 17d4a6db..46bb995a 100644 --- a/lib/input/sketch/entities/layers/shape_path.dart +++ b/lib/input/sketch/entities/layers/shape_path.dart @@ -35,13 +35,13 @@ class ShapePath extends AbstractShapeLayer implements SketchNodeFactory { Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/layers/sketch_text.dart b/lib/input/sketch/entities/layers/sketch_text.dart index 037fd149..e8f279dc 100644 --- a/lib/input/sketch/entities/layers/sketch_text.dart +++ b/lib/input/sketch/entities/layers/sketch_text.dart @@ -49,13 +49,13 @@ class SketchText extends SketchNode implements SketchNodeFactory, Text { Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; @@ -201,28 +201,28 @@ class SketchText extends SketchNode implements SketchNodeFactory, Text { var attributedString; @override - void set automaticallyDrawOnUnderlyingPath( + set automaticallyDrawOnUnderlyingPath( _automaticallyDrawOnUnderlyingPath) { // TODO: implement automaticallyDrawOnUnderlyingPath } @override - void set dontSynchroniseWithSymbol(_dontSynchroniseWithSymbol) { + set dontSynchroniseWithSymbol(_dontSynchroniseWithSymbol) { // TODO: implement dontSynchroniseWithSymbol } @override - void set glyphBounds(_glyphBounds) { + set glyphBounds(_glyphBounds) { // TODO: implement glyphBounds } @override - void set lineSpacingBehaviour(_lineSpacingBehaviour) { + set lineSpacingBehaviour(_lineSpacingBehaviour) { // TODO: implement lineSpacingBehaviour } @override - void set textBehaviour(_textBehaviour) { + set textBehaviour(_textBehaviour) { // TODO: implement textBehaviour } } diff --git a/lib/input/sketch/entities/layers/star.dart b/lib/input/sketch/entities/layers/star.dart index 986a4af0..200d485d 100644 --- a/lib/input/sketch/entities/layers/star.dart +++ b/lib/input/sketch/entities/layers/star.dart @@ -35,13 +35,13 @@ class Star extends AbstractShapeLayer implements SketchNodeFactory { Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/layers/symbol_instance.dart b/lib/input/sketch/entities/layers/symbol_instance.dart index a9ab15c7..83d699b7 100644 --- a/lib/input/sketch/entities/layers/symbol_instance.dart +++ b/lib/input/sketch/entities/layers/symbol_instance.dart @@ -22,6 +22,7 @@ class SymbolInstance extends SketchNode implements SketchNodeFactory, PBSharedInstanceDesignNode { @override String CLASS_NAME = 'symbolInstance'; + @override final List overrideValues; final double scale; @override @@ -46,13 +47,13 @@ class SymbolInstance extends SketchNode Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; @@ -125,8 +126,8 @@ class SymbolInstance extends SketchNode ///Converting the [OverridableValue] into [PBSharedParameterValue] to be processed in intermediate phase. List _extractParameters() { - Set ovrNames = {}; - List sharedParameters = []; + var ovrNames = {}; + var sharedParameters = []; for (var overrideValue in overrideValues) { if (!ovrNames.contains(overrideValue.overrideName)) { var properties = extractParameter(overrideValue.overrideName); diff --git a/lib/input/sketch/entities/layers/symbol_master.dart b/lib/input/sketch/entities/layers/symbol_master.dart index 6ae1cd25..eca82f68 100644 --- a/lib/input/sketch/entities/layers/symbol_master.dart +++ b/lib/input/sketch/entities/layers/symbol_master.dart @@ -60,13 +60,13 @@ class SymbolMaster extends AbstractGroupLayer Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; @@ -164,8 +164,8 @@ class SymbolMaster extends AbstractGroupLayer ///Converting the [OverridableProperty] into [PBSharedParameterProp] to be processed in intermediate phase. List _extractParameters() { - Set ovrNames = {}; - List sharedParameters = []; + var ovrNames = {}; + var sharedParameters = []; for (var prop in overrideProperties) { if (!ovrNames.contains(prop.overrideName)) { var properties = AddMasterSymbolName(prop.overrideName, children); diff --git a/lib/input/sketch/entities/layers/triangle.dart b/lib/input/sketch/entities/layers/triangle.dart index 6147d4fd..df9b6c80 100644 --- a/lib/input/sketch/entities/layers/triangle.dart +++ b/lib/input/sketch/entities/layers/triangle.dart @@ -35,13 +35,13 @@ class Triangle extends AbstractShapeLayer implements SketchNodeFactory { Style _style; @override - void set isVisible(bool _isVisible) => this._isVisible = _isVisible; + set isVisible(bool _isVisible) => this._isVisible = _isVisible; @override bool get isVisible => _isVisible; @override - void set style(_style) => this._style = _style; + set style(_style) => this._style = _style; @override Style get style => _style; diff --git a/lib/input/sketch/entities/style/border.dart b/lib/input/sketch/entities/style/border.dart index d52ea472..5a033a95 100644 --- a/lib/input/sketch/entities/style/border.dart +++ b/lib/input/sketch/entities/style/border.dart @@ -32,5 +32,6 @@ class Border implements PBBorder{ this.thickness}); factory Border.fromJson(Map json) => _$BorderFromJson(json); + @override Map toJson() => _$BorderToJson(this); } diff --git a/lib/input/sketch/entities/style/border_options.dart b/lib/input/sketch/entities/style/border_options.dart index 6db5abb0..fb6185f3 100644 --- a/lib/input/sketch/entities/style/border_options.dart +++ b/lib/input/sketch/entities/style/border_options.dart @@ -22,5 +22,6 @@ class BorderOptions implements PBBorderOptions { ); factory BorderOptions.fromJson(Map json) => _$BorderOptionsFromJson(json); + @override Map toJson() => _$BorderOptionsToJson(this); } diff --git a/lib/input/sketch/entities/style/color.dart b/lib/input/sketch/entities/style/color.dart index ca97279f..d67185e4 100644 --- a/lib/input/sketch/entities/style/color.dart +++ b/lib/input/sketch/entities/style/color.dart @@ -7,10 +7,12 @@ part 'color.g.dart'; class Color implements PBColor { @JsonKey(name: '_class') final String classField; + @override double alpha, blue, green, red; Color({this.alpha, this.blue, this.classField, this.green, this.red}); factory Color.fromJson(Map json) => _$ColorFromJson(json); + @override Map toJson() => _$ColorToJson(this); } diff --git a/lib/input/sketch/entities/style/fill.dart b/lib/input/sketch/entities/style/fill.dart index 022252ac..063c15ac 100644 --- a/lib/input/sketch/entities/style/fill.dart +++ b/lib/input/sketch/entities/style/fill.dart @@ -35,5 +35,6 @@ class Fill implements PBFill { this.patternTileScale}); factory Fill.fromJson(Map json) => _$FillFromJson(json); + @override Map toJson() => _$FillToJson(this); } diff --git a/lib/input/sketch/entities/style/shared_style.dart b/lib/input/sketch/entities/style/shared_style.dart index 04078970..78fd7ac2 100644 --- a/lib/input/sketch/entities/style/shared_style.dart +++ b/lib/input/sketch/entities/style/shared_style.dart @@ -39,7 +39,7 @@ class SharedStyle with PBColorMixin { if (style.textStyle != null) { var source = style.textStyle; var fontDescriptor = source.fontDescriptor as FontDescriptor; - buffer.write('TextStyle ${name} = TextStyle(\n'); + buffer.write('TextStyle $name = TextStyle(\n'); if (fontDescriptor.fontName != null) { buffer.write('fontFamily: \'${source.fontDescriptor.fontName}\',\n'); } @@ -63,9 +63,9 @@ class SharedStyle with PBColorMixin { var color = toHex(source.fontColor); var defColor = findDefaultColor(color); if (defColor == null) { - buffer.write('color: Color(${color}),'); + buffer.write('color: Color($color),'); } else { - buffer.write('color: ${defColor},'); + buffer.write('color: $defColor,'); } } diff --git a/lib/input/sketch/entities/style/style.dart b/lib/input/sketch/entities/style/style.dart index dba78310..581d3025 100644 --- a/lib/input/sketch/entities/style/style.dart +++ b/lib/input/sketch/entities/style/style.dart @@ -31,7 +31,9 @@ class Style implements PBStyle { final List borders; final ColorControls colorControls; final ContextSettings contextSettings; + @override List fills, innerShadows, shadows; + @override @JsonKey(nullable: true) PBTextStyle textStyle; @@ -53,13 +55,14 @@ class Style implements PBStyle { TextStyle this.textStyle, }) { if (shadows != null) { - this.shadows = null; - this.innerShadows = null; + shadows = null; + innerShadows = null; hasShadow = true; } } factory Style.fromJson(Map json) => _$StyleFromJson(json); + @override Map toJson() => _$StyleToJson(this); @override diff --git a/lib/input/sketch/entities/style/text_style.dart b/lib/input/sketch/entities/style/text_style.dart index b2dc1956..d776c58b 100644 --- a/lib/input/sketch/entities/style/text_style.dart +++ b/lib/input/sketch/entities/style/text_style.dart @@ -15,6 +15,7 @@ class TextStyle implements PBTextStyle { @override @JsonKey(ignore: true) PBFontDescriptor fontDescriptor; + @override @JsonKey(ignore: true) PBParagraphStyle paragraphStyle; @JsonKey(ignore: true) @@ -97,6 +98,7 @@ class TextStyle implements PBTextStyle { factory TextStyle.fromJson(Map json) => _$TextStyleFromJson(json); + @override Map toJson() => _$TextStyleToJson(this); @override diff --git a/lib/input/sketch/helper/sketch_project.dart b/lib/input/sketch/helper/sketch_project.dart index 4601b959..d13ded3a 100644 --- a/lib/input/sketch/helper/sketch_project.dart +++ b/lib/input/sketch/helper/sketch_project.dart @@ -39,7 +39,7 @@ class SketchProject extends DesignProject { List _setSharedStyles() { try { - List sharedStyles = []; + var sharedStyles = []; var jsonData = _ids.documentFile; var doc = Document.fromJson(jsonData); if (doc.layerStyles != null) { diff --git a/lib/input/sketch/services/input_design.dart b/lib/input/sketch/services/input_design.dart index ed780570..43e6e33c 100644 --- a/lib/input/sketch/services/input_design.dart +++ b/lib/input/sketch/services/input_design.dart @@ -49,7 +49,7 @@ class InputDesignService { if (file.isFile && fileName.contains(IMAGE_DIR_NAME)) { final data = file.content as List; final name = fileName.replaceAll(IMAGE_DIR_NAME, ''); - File('${MainInfo().outputPath}pngs/${name}').writeAsBytesSync(data); + File('${MainInfo().outputPath}pngs/$name').writeAsBytesSync(data); } } } diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index 552a97cd..28879f9a 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -9,6 +9,7 @@ class Flexible extends PBVisualIntermediateNode { @override var currentContext; + @override final String UUID; @override @@ -33,8 +34,10 @@ class Flexible extends PBVisualIntermediateNode { this.child = child; } + @override Point topLeftCorner; + @override Point bottomRightCorner; @override diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index 3117a5be..ba892e31 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -6,8 +6,10 @@ import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class InjectedPositioned extends PBIntermediateNode implements PBInjectedIntermediate { + @override PBContext currentContext; + @override final String UUID; final PositionedValueHolder valueHolder; diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index f8b6365a..fa67b3d3 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -8,14 +8,17 @@ class Padding extends PBVisualIntermediateNode { double left, right, top, bottom, screenWidth, screenHeight; + @override final String UUID; Map padding; @override PBContext currentContext; + @override Point topLeftCorner; + @override Point bottomRightCorner; Padding(this.UUID, diff --git a/lib/interpret_and_optimize/entities/alignments/spacer.dart b/lib/interpret_and_optimize/entities/alignments/spacer.dart index 617161ad..162fc4ed 100644 --- a/lib/interpret_and_optimize/entities/alignments/spacer.dart +++ b/lib/interpret_and_optimize/entities/alignments/spacer.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class Spacer extends PBVisualIntermediateNode { int flex; + @override final String UUID; @override diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 91d76c82..1170fec1 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -27,6 +27,7 @@ class InheritedScaffold extends PBVisualIntermediateNode bool isHomeScreen = false; + @override PBIntermediateNode get child => getAttributeNamed('body')?.attributeNode; PBIntermediateNode get navbar => getAttributeNamed('appBar')?.attributeNode; @@ -34,6 +35,7 @@ class InheritedScaffold extends PBVisualIntermediateNode PBIntermediateNode get tabbar => getAttributeNamed('bottomNavigationBar')?.attributeNode; + @override set child(PBIntermediateNode node) { if (!hasAttribute('body')) { addAttribute(PBAttribute('body', attributeNodes: [node])); diff --git a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart index 284c4ffa..51030f20 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart @@ -30,8 +30,8 @@ List handleFlex(bool isVertical, Point topLeft, // This list will store the final wrapped children var resultingChildren = []; - for (int i = 0; i < children.length; i++) { - PBIntermediateNode child = children[i]; + for (var i = 0; i < children.length; i++) { + var child = children[i]; // Handle spacer of middle child if (i > 0) { diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 74a1b6e6..5f8d75cd 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -20,6 +20,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { @override final String UUID; + @override Map alignment = {}; @override diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index 158c4b4c..7d4c91c5 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -32,14 +32,14 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode @override void alignChildren() { - assert(false, 'Attempted to align children on class type [${runtimeType}]'); + assert(false, 'Attempted to align children on class type [$runtimeType]'); return null; } @override bool satisfyRules( PBIntermediateNode currentNode, PBIntermediateNode nextNode) { - assert(false, 'Attempted to satisfyRules for class type [${runtimeType}]'); + assert(false, 'Attempted to satisfyRules for class type [$runtimeType]'); return null; } @@ -47,7 +47,7 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { assert( - false, 'Attempted to generateLayout for class type [${runtimeType}]'); + false, 'Attempted to generateLayout for class type [$runtimeType]'); return null; } } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index c052c3eb..13ab2085 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -18,13 +18,13 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode getAttributeNamed('children')?.attributeNodes; ///The rules of the layout. MAKE SURE TO REGISTER THEIR CUSTOM RULES - List _layoutRules = []; + final List _layoutRules; ///Getting the rules of the layout List get rules => List.from(_layoutRules); ///Exceptions to the rules of the layout. MAKE SURE TO REGISTER THEIR CUSTOM EXCEPTIONS - List _exceptions = []; + final List _exceptions; ///Getting the exceptions of the rules. List get exceptions => List.from(_exceptions); diff --git a/lib/interpret_and_optimize/helpers/pb_gen_cache.dart b/lib/interpret_and_optimize/helpers/pb_gen_cache.dart index 40f2b85e..f015b827 100644 --- a/lib/interpret_and_optimize/helpers/pb_gen_cache.dart +++ b/lib/interpret_and_optimize/helpers/pb_gen_cache.dart @@ -10,7 +10,7 @@ class PBGenCache { /// Cache where the key is the doObjectId and the value is the paths associated /// to the doObjectId - Map> _cache = {}; + final Map> _cache = {}; /// Associates `path` to `doObjectId` in this cache. void setPathToCache(String doObjectId, String path) { @@ -44,7 +44,7 @@ class PBGenCache { for (var targetPath in targetPaths) { // Tokenize [filePath] and the path to the file of [doObjectId] - List filePathTokens = filePath.split('/') + var filePathTokens = filePath.split('/') ..removeLast() ..removeAt(0); if (targetPath == filePath) { @@ -65,23 +65,23 @@ class PBGenCache { } // Case for when backtracking is not needed to get to [targetPath] else if (filePathTokens.isEmpty) { - String result = './'; - for (String folder in targetPathTokens) { + var result = './'; + for (var folder in targetPathTokens) { result = '$result$folder/'; } paths.add('$result$targetFileName'); } // Case for when backtracking is needed to get to [targetPath] else { - String result = ''; + var result = ''; // Backtrack - for (int i = 0; i < filePathTokens.length; i++) { + for (var i = 0; i < filePathTokens.length; i++) { result = '$result../'; } // Add necessary folders - for (int i = 0; i < targetPathTokens.length; i++) { + for (var i = 0; i < targetPathTokens.length; i++) { result = '$result${targetPathTokens[i]}/'; } paths.add('$result$targetFileName'); diff --git a/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart b/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart index 39daca57..233388d8 100644 --- a/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart +++ b/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart @@ -30,11 +30,11 @@ class ImageReferenceStorage { addReference(name, '${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png')) { File('${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png') - .copySync('${MainInfo().outputPath}pngs/${name}.png'); + .copySync('${MainInfo().outputPath}pngs/$name.png'); return true; } if (addReference(name, path)) { - var imgPath = '${MainInfo().outputPath}pngs/${name}.png'; + var imgPath = '${MainInfo().outputPath}pngs/$name.png'; if (!File(imgPath).existsSync()) { File(imgPath).createSync(recursive: true); } diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index 67a3ccb0..d861c1fe 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -58,7 +58,7 @@ class PBPluginListHelper { /// Returns the PluginNode associated if it exists. PBEgg returnAllowListNodeIfExists(DesignNode node) { // InjectedContainer(null,null)..subsemantic = ''; - for (String key in allowListNames.keys) { + for (var key in allowListNames.keys) { if (node.name.contains(key)) { return allowListNames[key].generatePluginNode( Point(node.boundaryRectangle.x, node.boundaryRectangle.y), diff --git a/lib/interpret_and_optimize/helpers/pb_symbol_storage.dart b/lib/interpret_and_optimize/helpers/pb_symbol_storage.dart index b2418b7e..4d9b4948 100644 --- a/lib/interpret_and_optimize/helpers/pb_symbol_storage.dart +++ b/lib/interpret_and_optimize/helpers/pb_symbol_storage.dart @@ -37,7 +37,7 @@ class PBSymbolStorage { if (_pbSharedInstanceNodes.containsKey(symbolInstance.UUID)) { return false; } - await PBSharedInterAggregationService().analyzeSharedNode(symbolInstance); + PBSharedInterAggregationService().analyzeSharedNode(symbolInstance); _pbSharedInstanceNodes['${symbolInstance.UUID}'] = symbolInstance; return true; } @@ -48,7 +48,7 @@ class PBSymbolStorage { if (_pbSharedMasterNodes.containsKey(masterNode.UUID)) { return false; } - await PBSharedInterAggregationService().analyzeSharedNode(masterNode); + PBSharedInterAggregationService().analyzeSharedNode(masterNode); _pbSharedMasterNodes['${masterNode.UUID}'] = masterNode; return true; } @@ -76,12 +76,10 @@ class PBSymbolStorage { return node; } - /** - * Removes the symbol with given [id]. - * - * Returns [true] if the object was successfuly removed, - * [false] if the object did not exist. - */ + /// Removes the symbol with given [id]. + /// + /// Returns [true] if the object was successfuly removed, + /// [false] if the object did not exist. bool removeSymbolWithId(String id) { return (_pbSharedMasterNodes.remove(id) != null); } diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index b649a246..11905d75 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -52,7 +52,7 @@ class PBSharedInterAggregationService { rootChildNode, targetUUID); if (prop.value == null) { // add Designer Warning here, not even sure if this is the designers fault or not - log.warning('UUID: ${targetUUID} not found in searchNodeByUUID'); + log.warning('UUID: $targetUUID not found in searchNodeByUUID'); } if ((prop.value != null) && (prop.type == PBSharedInstanceIntermediateNode)) { diff --git a/lib/main.dart b/lib/main.dart index 09aa2aa6..2c416afe 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -271,7 +271,7 @@ Future checkConfigFile() async { MainInfo().deviceId = configMap['device_id']; } - await addToAmplitude(); + addToAmplitude(); } /// Gets the homepath of the user according to their OS diff --git a/test/lib/input_services/appbar_detection_test.dart b/test/lib/input_services/appbar_detection_test.dart index f332b013..475c367e 100644 --- a/test/lib/input_services/appbar_detection_test.dart +++ b/test/lib/input_services/appbar_detection_test.dart @@ -27,7 +27,7 @@ void main() { }); test('Checking for appbar', () { - PBEgg pNode = helper.returnAllowListNodeIfExists(sketchNode); + var pNode = helper.returnAllowListNodeIfExists(sketchNode); expect(pNode.runtimeType, InjectedAppbar); }); }); diff --git a/test/lib/input_services/input_to_pbdl_test.dart b/test/lib/input_services/input_to_pbdl_test.dart index 8a7b432a..3aac7ee9 100644 --- a/test/lib/input_services/input_to_pbdl_test.dart +++ b/test/lib/input_services/input_to_pbdl_test.dart @@ -32,7 +32,7 @@ void main() { }); test('Figma Test', () async { var figmaNodeTree = - await FigmaController().generateFigmaTree(result, outputPath); + FigmaController().generateFigmaTree(result, outputPath); expect(figmaNodeTree != null, true); expect(figmaNodeTree is FigmaProject, true); @@ -51,7 +51,7 @@ void main() { tearDownAll(() { Process.runSync( '${Directory.current.path}/lib/generation/helperScripts/shell-proxy.sh', - ['rm -rf ${outputPath}']); + ['rm -rf $outputPath']); }); }, skip: !Platform.environment.containsKey('FIG_API_KEY'), diff --git a/test/lib/layouts/layout_post_rules_test.dart b/test/lib/layouts/layout_post_rules_test.dart index 91a1ab86..cc03f0e4 100644 --- a/test/lib/layouts/layout_post_rules_test.dart +++ b/test/lib/layouts/layout_post_rules_test.dart @@ -12,7 +12,7 @@ class InheritedContainerMockWrapper extends Mock implements InheritedContainer { var child; @override void addChild(PBIntermediateNode node) { - this.child = node; + child = node; } } diff --git a/test/lib/output_services/dependency_writer_test.dart b/test/lib/output_services/dependency_writer_test.dart index 60d879d7..f8daf78a 100644 --- a/test/lib/output_services/dependency_writer_test.dart +++ b/test/lib/output_services/dependency_writer_test.dart @@ -19,9 +19,9 @@ void main() { await writer.submitDependencies(yamlAbsPath); var lineHttp = -1; var lineShelf = -1; - var readYaml = await File(yamlAbsPath).readAsLinesSync(); - lineHttp = await readYaml.indexOf(' http_parser: ^3.1.4'); - lineShelf = await readYaml.indexOf(' shelf_proxy: ^0.1.0+7'); + var readYaml = File(yamlAbsPath).readAsLinesSync(); + lineHttp = readYaml.indexOf(' http_parser: ^3.1.4'); + lineShelf = readYaml.indexOf(' shelf_proxy: ^0.1.0+7'); expect(lineHttp >= 0, true); expect(lineShelf >= 0, true); }, timeout: Timeout(Duration(minutes: 1))); diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index 9b27c240..f86cc748 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -101,7 +101,7 @@ void main() { await fss.setUpDirectories(); when(project.fileStructureStrategy).thenReturn(fss); - projectBuilder = await FlutterProjectBuilder( + projectBuilder = FlutterProjectBuilder( projectName: outputPath, mainTree: project, pageWriter: PBFlutterWriter()); From c7d980496042f74d6284ccda677f293023296d21 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Mon, 17 May 2021 14:58:55 -0600 Subject: [PATCH 090/404] WIP included the Import Helper in the generation manager to access all the imports that are being recorded. --- .../import_helper.dart | 11 +++- .../state_management/provider_middleware.dart | 3 +- .../generators/pb_flutter_generator.dart | 4 +- .../generators/pb_generation_manager.dart | 6 +- lib/generation/generators/pb_generator.dart | 3 +- .../pb_generation_configuration.dart | 63 +++++++++---------- test/lib/generation/generator_test.dart | 3 +- .../padding_dynamic_size_test.dart | 4 +- .../output_services/project_builder_test.dart | 1 + 9 files changed, 57 insertions(+), 41 deletions(-) diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 6ee51d0c..5f353478 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -9,7 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/generation/flutter_project_builder/file_writer_observer.dart'; class ImportHelper implements FileWriterObserver { - Map imports = {}; + final Map imports = {}; /// Traverse the [node] tree, check if any nodes need importing, /// and add the relative import from [path] to the [node] @@ -60,8 +60,15 @@ class ImportHelper implements FileWriterObserver { return currentImports; } + void addImport(String import, String UUID){ + if(import != null && UUID != null){ + imports[UUID] = import; + } + } @override void fileCreated(String filePath, String fileUUID) { - imports[fileUUID] = filePath; + if(filePath != null && fileUUID != null){ + imports[fileUUID] = filePath; + } } } diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index cf638e3c..445761b5 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; @@ -82,7 +83,7 @@ class ProviderMiddleware extends Middleware { var parentDirectory = getName(node.name).snakeCase; // Generate model's imports - var modelGenerator = PBFlutterGenerator( + var modelGenerator = PBFlutterGenerator(ImportHelper(), data: PBGenerationViewData() ..addImport('package:flutter/material.dart')); // Write model class for current node diff --git a/lib/generation/generators/pb_flutter_generator.dart b/lib/generation/generators/pb_flutter_generator.dart index 7f04b3f4..7382713c 100644 --- a/lib/generation/generators/pb_flutter_generator.dart +++ b/lib/generation/generators/pb_flutter_generator.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; @@ -8,7 +9,8 @@ import 'package:quick_log/quick_log.dart'; class PBFlutterGenerator extends PBGenerationManager { var log = Logger('Flutter Generator'); final DEFAULT_STRATEGY = EmptyPageTemplateStrategy(); - PBFlutterGenerator({PBGenerationViewData data}) : super(data: data) { + PBFlutterGenerator(ImportHelper importHelper, {PBGenerationViewData data}) + : super(importHelper, data: data) { body = StringBuffer(); } diff --git a/lib/generation/generators/pb_generation_manager.dart b/lib/generation/generators/pb_generation_manager.dart index 6bb4f070..cfab3237 100644 --- a/lib/generation/generators/pb_generation_manager.dart +++ b/lib/generation/generators/pb_generation_manager.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -12,11 +13,14 @@ abstract class PBGenerationManager { Type rootType; + /// In charge of processing all the imports of the files that are being written in the file sytem + ImportHelper importProcessor; + PBGenerationViewData _data; PBGenerationViewData get data => _data; set data(PBGenerationViewData data) => _data = data; - PBGenerationManager({data}) { + PBGenerationManager(this.importProcessor, {data}) { _data = data; } diff --git a/lib/generation/generators/pb_generator.dart b/lib/generation/generators/pb_generator.dart index 80f491bd..fa286696 100644 --- a/lib/generation/generators/pb_generator.dart +++ b/lib/generation/generators/pb_generator.dart @@ -18,8 +18,7 @@ abstract class PBGenerator { set templateStrategy(TemplateStrategy strategy) => _templateStrategy = strategy; - PBGenerationManager _manager = - PBFlutterGenerator(data: PBGenerationViewData()); + PBGenerationManager _manager; set manager(PBGenerationManager generationManager) => _manager = generationManager; PBGenerationManager get manager => _manager; diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 8c4bba07..9916dc14 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; +import 'package:parabeac_core/generation/generators/util/topo_tree_iterator.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; @@ -14,11 +15,9 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; @@ -39,17 +38,12 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ///The manager in charge of the independent [PBGenerator]s by providing an interface for adding imports, global variables, etc. /// ///The default [PBGenerationManager] will be [PBFlutterGenerator] - PBGenerationManager _generationManager; + PBGenerationManager generationManager; - /// PageWriter to be used for generation - PBPageWriter _pageWriter = PBFlutterWriter(); // Default to Flutter - PBPageWriter get pageWriter => _pageWriter; - - set pageWriter(PBPageWriter pageWriter) => _pageWriter = pageWriter; + ImportHelper _importProcessor; - PBGenerationManager get generationManager => _generationManager; - set generationManager(PBGenerationManager manager) => - _generationManager = manager; + /// PageWriter to be used for generation + PBPageWriter pageWriter = PBFlutterWriter(); // Default to Flutter final Map _dependencies = {}; Iterable> get dependencies => _dependencies.entries; @@ -59,7 +53,9 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { GenerationConfiguration() { logger = Logger(runtimeType.toString()); - _generationManager = PBFlutterGenerator(data: PBGenerationViewData()); + _importProcessor ??= ImportHelper(); + generationManager ??= + PBFlutterGenerator(_importProcessor, data: PBGenerationViewData()); } ///This is going to modify the [PBIntermediateNode] in order to affect the structural patterns or file structure produced. @@ -116,9 +112,11 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await setUpConfiguration(); pbProject.fileStructureStrategy = fileStructureStrategy; - for (var tree in pbProject.forest) { + var trees = IntermediateTopoIterator(pbProject.forest); + while (trees.moveNext()) { + var tree = trees.current; tree.data.addImport('package:flutter/material.dart'); - _generationManager.data = tree.data; + generationManager.data = tree.data; var fileName = tree.rootNode?.name?.snakeCase ?? 'no_name_found'; // Relative path to the file to create @@ -135,7 +133,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } await _iterateNode(tree.rootNode); - _commitImports(tree.rootNode, tree.name.snakeCase, fileName); + // _commitImports(tree.rootNode, tree.name.snakeCase, fileName); if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { tree.rootNode.currentContext.project.genProjectData.commandQueue @@ -143,20 +141,20 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { tree.rootNode.currentContext.tree.data.platform, '$fileName', '$fileName${getPlatformOrientationName(tree.rootNode)}.dart', - _generationManager.generate(tree.rootNode), + generationManager.generate(tree.rootNode), )); } else if (tree.rootNode is InheritedScaffold) { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(WriteScreenCommand( '$fileName.dart', '${tree.name}', - _generationManager.generate(tree.rootNode), + generationManager.generate(tree.rootNode), )); } else { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(WriteSymbolCommand( '$fileName.dart', - _generationManager.generate(tree.rootNode), + generationManager.generate(tree.rootNode), )); } } @@ -165,14 +163,14 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { void registerMiddleware(Middleware middleware) { if (middleware != null) { - middleware.generationManager = _generationManager; + middleware.generationManager = generationManager; _middleware.add(middleware); } } Future setUpConfiguration() async { fileStructureStrategy = FlutterFileStructureStrategy( - pbProject.projectAbsPath, _pageWriter, pbProject); + pbProject.projectAbsPath, pageWriter, pbProject); commandObservers.add(fileStructureStrategy); // Execute command queue @@ -185,26 +183,27 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await fileStructureStrategy.setUpDirectories(); } - void _commitImports( - PBIntermediateNode node, String directoryName, String fileName) { - var nodePaths = PBGenCache() - .getPaths(node is PBSharedMasterNode ? node.SYMBOL_ID : node.UUID); - var imports = {}; - // Fetch imports for each path - nodePaths.forEach( - (path) => imports.addAll(ImportHelper.findImports(node, path))); - imports.forEach(node.managerData.addImport); - } + //TODO delete + // void _commitImports( + // PBIntermediateNode node, String directoryName, String fileName) { + // var nodePaths = PBGenCache() + // .getPaths(node is PBSharedMasterNode ? node.SYMBOL_ID : node.UUID); + // var imports = {}; + // // Fetch imports for each path + // nodePaths.forEach( + // (path) => imports.addAll(ImportHelper.findImports(node, path))); + // imports.forEach(node.managerData.addImport); + // } Future _commitDependencies(String projectName) async { - var writer = _pageWriter; + var writer = pageWriter; if (writer is PBFlutterWriter) { writer.submitDependencies(projectName + '/pubspec.yaml'); } } void _setMainScreen(InheritedScaffold node, String outputMain) async { - var writer = _pageWriter; + var writer = pageWriter; if (writer is PBFlutterWriter) { await writer.writeMainScreenWithHome( node.name, diff --git a/test/lib/generation/generator_test.dart b/test/lib/generation/generator_test.dart index d79beb64..41b1c878 100644 --- a/test/lib/generation/generator_test.dart +++ b/test/lib/generation/generator_test.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; @@ -82,7 +83,7 @@ void main() { when(mockInheritedText.text).thenReturn('Test Text'); - mockManager = PBFlutterGenerator(); + mockManager = PBFlutterGenerator(ImportHelper()); mockGenerator = PBContainerGenerator(); mockGenerator.manager = mockManager; diff --git a/test/lib/input_services/padding_dynamic_size_test.dart b/test/lib/input_services/padding_dynamic_size_test.dart index 42499aec..ec015f0c 100644 --- a/test/lib/input_services/padding_dynamic_size_test.dart +++ b/test/lib/input_services/padding_dynamic_size_test.dart @@ -1,4 +1,5 @@ import 'package:mockito/mockito.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -20,7 +21,8 @@ void main() { currentContext = ContextMock(); when(currentContext.screenTopLeftCorner).thenReturn(Point(215, -295)); when(currentContext.screenBottomRightCorner).thenReturn(Point(590, 955)); - when(currentContext.generationManager).thenReturn(PBFlutterGenerator()); + when(currentContext.generationManager) + .thenReturn(PBFlutterGenerator(ImportHelper())); currentChild = NodeMock(); when(currentChild.currentContext).thenReturn(currentContext); diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index f86cc748..a082c94a 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -74,6 +74,7 @@ void main() { when(intermediateTree.rootNode).thenReturn(scaffold); when(intermediateTree.name).thenReturn('testTree'); when(intermediateTree.data).thenReturn(PBGenerationViewData()); + when(intermediateTree.dependentsOn).thenReturn([]); when(project.projectName).thenReturn( '${Directory.current.path}/test/lib/output_services/temp2/'); From 2b3e0fe37cb7bded054f2a26053d5775071078a2 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 17 May 2021 17:38:04 -0600 Subject: [PATCH 091/404] Make tree name snakeCase for file-writing. --- .../generation_configuration/pb_generation_configuration.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 08ffcbd5..45ec4d7a 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -149,7 +149,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(WriteScreenCommand( '$fileName.dart', - '${tree.name}', + '${tree.name.snakeCase}', await _generationManager.generate(tree.rootNode), )); } else { From 1090bd9aa3e7a2327db67e6bc6794b13466799eb Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 17 May 2021 18:10:52 -0600 Subject: [PATCH 092/404] Writing symbols now takes optional relative path. --- .../commands/write_symbol_command.dart | 11 +++++++++-- .../pb_generation_configuration.dart | 12 +++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index e620639d..e3a9b4e6 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -5,15 +5,22 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure class WriteSymbolCommand extends NodeFileStructureCommand { String name; final String SYMBOL_PATH = 'lib/widgets'; + String relativePath; - WriteSymbolCommand(this.name, String code) : super(code); + WriteSymbolCommand(this.name, String code, {this.relativePath}) : super(code); /// Writes a symbol file containing [data] with [name] as its filename. /// /// Returns path to the file that was created. @override Future write(FileStructureStrategy strategy) { - var absPath = '${strategy.GENERATED_PROJECT_PATH}$SYMBOL_PATH/$name'; + var absPath; + if (relativePath.isEmpty) { + absPath = '${strategy.GENERATED_PROJECT_PATH}$SYMBOL_PATH/$name'; + } else { + absPath = + '${strategy.GENERATED_PROJECT_PATH}$SYMBOL_PATH/$relativePath$name'; + } writeDataToFile(code, absPath); return Future.value(absPath); } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 45ec4d7a..66d366d3 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -153,11 +153,13 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await _generationManager.generate(tree.rootNode), )); } else { - tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(WriteSymbolCommand( - '$fileName.dart', - await _generationManager.generate(tree.rootNode), - )); + tree.rootNode.currentContext.project.genProjectData.commandQueue.add( + WriteSymbolCommand( + '$fileName.dart', + await _generationManager.generate(tree.rootNode), + relativePath: tree.name.snakeCase + '/', + ), + ); } } await _commitDependencies(pb_project.projectName); From 9466cacfd2de0a33697fea6433aaf608841419b0 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 17 May 2021 18:11:31 -0600 Subject: [PATCH 093/404] Change `view` path to `widgets` --- .../file_structure_strategy/pb_file_structure_strategy.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 34b7341b..aa4dfde5 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -19,7 +19,7 @@ abstract class FileStructureStrategy implements CommandInvoker { /// ///The views is anything that is not a screen, for example, symbol masters ///are going to be generated in this folder if not specified otherwise. - final RELATIVE_VIEW_PATH = 'lib/view/'; + final RELATIVE_VIEW_PATH = 'lib/widgets/'; ///The path of where all the screens are going to be generated. final RELATIVE_SCREEN_PATH = 'lib/screens/'; From c5f3f42622f45d7ba692d306f61cd55c6e2ecef0 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Mon, 17 May 2021 22:50:58 -0600 Subject: [PATCH 094/404] Refactored the PBContext to replace the context that contained information about the size structure. Finally, made the import helper to track the files that were being written into the file system. --- lib/controllers/controller.dart | 1 - lib/eggs/injected_app_bar.dart | 5 +--- lib/eggs/injected_back_arrow.dart | 4 +--- lib/eggs/injected_tab.dart | 5 +--- lib/eggs/injected_tab_bar.dart | 7 ++---- .../import_helper.dart | 15 ++++++++---- .../pb_attribute_gen_helper.dart | 4 ++-- .../pb_box_decoration_gen_helper.dart | 5 ++-- .../attribute-helper/pb_color_gen_helper.dart | 5 ++-- .../pb_generator_context.dart | 15 ------------ .../attribute-helper/pb_size_helper.dart | 7 ++---- .../generators/helpers/pb_gen_helper.dart | 4 ++-- .../generators/helpers/pb_layout_helper.dart | 5 ++-- .../generators/layouts/pb_column_gen.dart | 7 ++---- .../generators/layouts/pb_layout_gen.dart | 4 ++-- .../generators/layouts/pb_row_gen.dart | 4 ++-- .../generators/layouts/pb_scaffold_gen.dart | 15 +++++------- .../generators/layouts/pb_stack_gen.dart | 5 ++-- .../utils/middleware_utils.dart | 11 ++++----- .../generators/pb_flutter_generator.dart | 15 ++++++------ lib/generation/generators/pb_generator.dart | 24 ++++--------------- .../symbols/pb_instancesym_gen.dart | 9 ++++--- .../generators/symbols/pb_mastersym_gen.dart | 5 ++-- .../symbols/pb_sym_mas_param_gen.dart | 5 ++-- .../generators/util/topo_tree_iterator.dart | 24 ++++++++++--------- .../pb_generation_configuration.dart | 16 ++++--------- .../value_objects/generator_adapter.dart | 4 ++-- .../bloc_state_template_strategy.dart | 4 ++-- .../empty_page_template_strategy.dart | 4 ++-- .../inline_template_strategy.dart | 4 ++-- .../pb_template_strategy.dart | 4 ++-- .../stateful_template_strategy.dart | 4 ++-- .../stateless_template_strategy.dart | 4 ++-- .../visual-widgets/pb_align_gen.dart | 5 ++-- .../visual-widgets/pb_bitmap_gen.dart | 6 ++--- .../visual-widgets/pb_container_gen.dart | 5 ++-- .../visual-widgets/pb_flexible_gen.dart | 4 ++-- .../visual-widgets/pb_padding_gen.dart | 5 ++-- .../visual-widgets/pb_positioned_gen.dart | 5 ++-- .../visual-widgets/pb_shape_group_gen.dart | 5 ++-- .../visual-widgets/pb_spacer_gen.dart | 4 ++-- .../visual-widgets/pb_text_gen.dart | 5 ++-- .../prototyping/pb_prototype_gen.dart | 5 ++-- .../helpers/pb_context.dart | 16 ++++++++++++- .../helpers/pb_intermediate_node_tree.dart | 22 ++++++++++++++--- test/lib/generation/generator_test.dart | 5 +--- test/lib/generation/import_test.dart | 14 +++++------ .../output_services/project_builder_test.dart | 4 +++- 48 files changed, 163 insertions(+), 201 deletions(-) delete mode 100644 lib/generation/generators/attribute-helper/pb_generator_context.dart diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index 663aae82..d3ce3982 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -1,6 +1,5 @@ import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; -import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/generation/generators/writers/pb_traversal_adapter_writer.dart'; import 'package:parabeac_core/generation/pre-generation/pre_generation_service.dart'; diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index f03754ed..042c4885 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -1,6 +1,4 @@ -import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; @@ -99,8 +97,7 @@ class PBAppBarGenerator extends PBGenerator { PBAppBarGenerator() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { generatorContext.sizingContext = SizingValueContext.PointValue; if (source is InjectedAppbar) { var buffer = StringBuffer(); diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index e8f26f1e..2799a9d3 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -1,5 +1,4 @@ import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; @@ -46,8 +45,7 @@ class PBBackArrowGenerator extends PBGenerator { PBBackArrowGenerator() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is InjectedBackArrow) { return 'BackButton()'; } diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index e10c3dad..27ea76d5 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -1,6 +1,4 @@ import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; -import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; @@ -95,8 +93,7 @@ class PBTabGenerator extends PBGenerator { PBTabGenerator() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is Tab) { var buffer = StringBuffer(); buffer.write('BottomNavigationBarItem('); diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 95d9fbe4..b4a9d6bd 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -1,7 +1,5 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; -import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; @@ -75,8 +73,7 @@ class PBTabBarGenerator extends PBGenerator { PBTabBarGenerator() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { generatorContext.sizingContext = SizingValueContext.PointValue; if (source is InjectedTabBar) { var tabs = source.tabs; @@ -88,7 +85,7 @@ class PBTabBarGenerator extends PBGenerator { buffer.write('items:['); for (var i = 0; i < tabs.length; i++) { buffer.write('BottomNavigationBarItem('); - var res = manager.generate(tabs[i].child); + var res = generatorContext.generationManager.generate(tabs[i].child); buffer.write('icon: $res,'); buffer.write('title: Text(""),'); buffer.write('),'); diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 5f353478..c6c288da 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -60,15 +60,22 @@ class ImportHelper implements FileWriterObserver { return currentImports; } - void addImport(String import, String UUID){ - if(import != null && UUID != null){ + String getImport(String UUID) { + if (imports.containsKey(UUID)) { + return imports[UUID]; + } + } + + void addImport(String import, String UUID) { + if (import != null && UUID != null) { imports[UUID] = import; } } + @override void fileCreated(String filePath, String fileUUID) { - if(filePath != null && fileUUID != null){ - imports[fileUUID] = filePath; + if (filePath != null && fileUUID != null) { + imports[fileUUID] = filePath; } } } diff --git a/lib/generation/generators/attribute-helper/pb_attribute_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_attribute_gen_helper.dart index 1c1afeaa..7ceb6691 100644 --- a/lib/generation/generators/attribute-helper/pb_attribute_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_attribute_gen_helper.dart @@ -1,10 +1,10 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; ///For example, generating the size of Container or any other widget. abstract class PBAttributesHelper extends PBGenerator { PBAttributesHelper() : super(); @override - String generate(PBIntermediateNode source, GeneratorContext generatorContext); + String generate(PBIntermediateNode source, PBContext generatorContext); } diff --git a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart index aca43a24..36dd80bc 100644 --- a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart @@ -1,15 +1,14 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_attribute_gen_helper.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBBoxDecorationHelper extends PBAttributesHelper { PBBoxDecorationHelper() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is InheritedContainer) { final buffer = StringBuffer(); buffer.write('decoration: BoxDecoration('); diff --git a/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart index e0a65d45..c67ff07f 100644 --- a/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart @@ -1,15 +1,14 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_attribute_gen_helper.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBColorGenHelper extends PBAttributesHelper { PBColorGenHelper() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { var statement = ''; if (source == null) { return statement; diff --git a/lib/generation/generators/attribute-helper/pb_generator_context.dart b/lib/generation/generators/attribute-helper/pb_generator_context.dart deleted file mode 100644 index d32e5ed9..00000000 --- a/lib/generation/generators/attribute-helper/pb_generator_context.dart +++ /dev/null @@ -1,15 +0,0 @@ -/// This class is responsible for sharing contextual data needed throughout the generation process. Generators will pass this information to it's children. -class GeneratorContext { - SizingValueContext sizingContext = SizingValueContext.PointValue; - - GeneratorContext({ - this.sizingContext, - }); -} - -enum SizingValueContext { - PointValue, - MediaQueryValue, - LayoutBuilderValue, - AppBarChild, -} diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index 0a0dd416..0e49d53f 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -1,15 +1,12 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_attribute_gen_helper.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBSizeHelper extends PBAttributesHelper { PBSizeHelper() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source.currentContext == null) { print('Tried generating a size but couldn\'t retrieve [currentContext]'); return ''; diff --git a/lib/generation/generators/helpers/pb_gen_helper.dart b/lib/generation/generators/helpers/pb_gen_helper.dart index 084afdca..6c20e7c5 100644 --- a/lib/generation/generators/helpers/pb_gen_helper.dart +++ b/lib/generation/generators/helpers/pb_gen_helper.dart @@ -1,8 +1,8 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; abstract class PBGenHelper { - String generate(PBIntermediateNode source, GeneratorContext context); + String generate(PBIntermediateNode source, PBContext context); bool containsIntermediateNode(PBIntermediateNode node); void registerIntemediateNode(PBIntermediateNode generator); } diff --git a/lib/generation/generators/helpers/pb_layout_helper.dart b/lib/generation/generators/helpers/pb_layout_helper.dart index 2cb4fc9a..b135ef22 100644 --- a/lib/generation/generators/helpers/pb_layout_helper.dart +++ b/lib/generation/generators/helpers/pb_layout_helper.dart @@ -1,14 +1,13 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/helpers/pb_gen_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBLayoutManager implements PBGenHelper { final List _registeredGenLayouts = []; @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source == null) { throw NullThrownError(); } diff --git a/lib/generation/generators/layouts/pb_column_gen.dart b/lib/generation/generators/layouts/pb_column_gen.dart index 560ec45c..75e7658d 100644 --- a/lib/generation/generators/layouts/pb_column_gen.dart +++ b/lib/generation/generators/layouts/pb_column_gen.dart @@ -1,16 +1,13 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_layout_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - -import '../pb_flutter_generator.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBColumnGenerator extends PBLayoutGenerator { PBColumnGenerator() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is PBIntermediateColumnLayout) { var buffer = StringBuffer(); buffer.write('Column('); diff --git a/lib/generation/generators/layouts/pb_layout_gen.dart b/lib/generation/generators/layouts/pb_layout_gen.dart index 98a1dcd3..38279c5e 100644 --- a/lib/generation/generators/layouts/pb_layout_gen.dart +++ b/lib/generation/generators/layouts/pb_layout_gen.dart @@ -1,12 +1,12 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; abstract class PBLayoutGenerator extends PBGenerator { PBLayoutGenerator() : super(); @override - String generate(PBIntermediateNode source, GeneratorContext generatorContext); + String generate(PBIntermediateNode source, PBContext generatorContext); String generateBodyBoilerplate(String body, {String layoutName = 'Column', diff --git a/lib/generation/generators/layouts/pb_row_gen.dart b/lib/generation/generators/layouts/pb_row_gen.dart index 67cbd8cd..4186e9ff 100644 --- a/lib/generation/generators/layouts/pb_row_gen.dart +++ b/lib/generation/generators/layouts/pb_row_gen.dart @@ -1,14 +1,14 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_layout_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBRowGenerator extends PBLayoutGenerator { PBRowGenerator() : super(); @override String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + PBIntermediateNode source, PBContext generatorContext) { if (source is PBIntermediateRowLayout) { var buffer = StringBuffer(); var counter = 0; diff --git a/lib/generation/generators/layouts/pb_scaffold_gen.dart b/lib/generation/generators/layouts/pb_scaffold_gen.dart index 79d8bc7f..004b969d 100644 --- a/lib/generation/generators/layouts/pb_scaffold_gen.dart +++ b/lib/generation/generators/layouts/pb_scaffold_gen.dart @@ -1,16 +1,15 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBScaffoldGenerator extends PBGenerator { PBScaffoldGenerator() : super(strategy: StatefulTemplateStrategy()); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { generatorContext.sizingContext = SizingValueContext.MediaQueryValue; var appBar = source.getAttributeNamed('appBar')?.attributeNode; var body = source.getAttributeNamed('body')?.attributeNode; @@ -26,18 +25,16 @@ class PBScaffoldGenerator extends PBGenerator { } if (appBar != null) { buffer.write('appBar: '); - var newGeneratorContext = - GeneratorContext(sizingContext: SizingValueContext.PointValue); - var appbarStr = appBar.generator.generate(appBar, newGeneratorContext); + generatorContext.sizingContext = SizingValueContext.PointValue; + var appbarStr = appBar.generator.generate(appBar, generatorContext); buffer.write('$appbarStr,\n'); } if (bottomNavBar != null) { buffer.write('bottomNavigationBar: '); - var newGeneratorContext = - GeneratorContext(sizingContext: SizingValueContext.PointValue); + generatorContext.sizingContext = SizingValueContext.PointValue; var navigationBar = - bottomNavBar.generator.generate(bottomNavBar, newGeneratorContext); + bottomNavBar.generator.generate(bottomNavBar, generatorContext); buffer.write('$navigationBar, \n'); } diff --git a/lib/generation/generators/layouts/pb_stack_gen.dart b/lib/generation/generators/layouts/pb_stack_gen.dart index 0f534634..369ef61f 100644 --- a/lib/generation/generators/layouts/pb_stack_gen.dart +++ b/lib/generation/generators/layouts/pb_stack_gen.dart @@ -1,14 +1,13 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBStackGenerator extends PBGenerator { PBStackGenerator() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is PBIntermediateStackLayout) { var buffer = StringBuffer(); buffer.write('Stack('); diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index a74d0c38..75ddef51 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -1,7 +1,7 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:recase/recase.dart'; class MiddlewareUtils { @@ -94,11 +94,10 @@ class MiddlewareUtils { {String type = 'var'}) => '$type ${node.name.camelCase};'; - static String generateVariableBody(node) => - (node?.generator?.generate(node ?? '', - GeneratorContext(sizingContext: SizingValueContext.PointValue)) ?? - '') + - ';'; + static String generateVariableBody(PBIntermediateNode node) { + node.currentContext.sizingContext = SizingValueContext.PointValue; + (node?.generator?.generate(node ?? '', node.currentContext) ?? '') + ';'; + } static String wrapOnLayout(String className) { return ''' diff --git a/lib/generation/generators/pb_flutter_generator.dart b/lib/generation/generators/pb_flutter_generator.dart index 7382713c..065a7146 100644 --- a/lib/generation/generators/pb_flutter_generator.dart +++ b/lib/generation/generators/pb_flutter_generator.dart @@ -1,9 +1,9 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/empty_page_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:quick_log/quick_log.dart'; class PBFlutterGenerator extends PBGenerationManager { @@ -106,17 +106,16 @@ class PBFlutterGenerator extends PBGenerationManager { if (rootNode == null) { return null; } - rootNode.generator.manager = this; + if (rootNode.generator == null) { log.error('Generator not registered for $rootNode'); } - return rootNode.generator?.templateStrategy?.generateTemplate( - rootNode, - this, - GeneratorContext(sizingContext: SizingValueContext.PointValue)) ?? + rootNode.currentContext.sizingContext = SizingValueContext.PointValue; + return rootNode.generator?.templateStrategy + ?.generateTemplate(rootNode, this, rootNode.currentContext) ?? ///if there is no [TemplateStrategy] we are going to use `DEFAULT_STRATEGY` - DEFAULT_STRATEGY.generateTemplate(rootNode, this, - GeneratorContext(sizingContext: SizingValueContext.PointValue)); + DEFAULT_STRATEGY.generateTemplate( + rootNode, this, rootNode.currentContext); } } diff --git a/lib/generation/generators/pb_generator.dart b/lib/generation/generators/pb_generator.dart index fa286696..9adac543 100644 --- a/lib/generation/generators/pb_generator.dart +++ b/lib/generation/generators/pb_generator.dart @@ -1,11 +1,7 @@ -import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; -import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; -import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/inline_template_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - -import 'attribute-helper/pb_generator_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; abstract class PBGenerator { final String OBJECTID = 'UUID'; @@ -13,22 +9,12 @@ abstract class PBGenerator { ///The [TemplateStrategy] that is going to be used to generate the boilerplate code around the node. /// ///The `default` [TemplateStrategy] is going to be [InlineTemplateStrategy] - TemplateStrategy _templateStrategy; - TemplateStrategy get templateStrategy => _templateStrategy; - set templateStrategy(TemplateStrategy strategy) => - _templateStrategy = strategy; - - PBGenerationManager _manager; - set manager(PBGenerationManager generationManager) => - _manager = generationManager; - PBGenerationManager get manager => _manager; - - PBGenerationViewData get data => _manager.data; + TemplateStrategy templateStrategy; PBGenerator({TemplateStrategy strategy}) { - _templateStrategy = strategy; - _templateStrategy ??= InlineTemplateStrategy(); + templateStrategy = strategy; + templateStrategy ??= InlineTemplateStrategy(); } - String generate(PBIntermediateNode source, GeneratorContext generatorContext); + String generate(PBIntermediateNode source, PBContext context); } diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 8424e508..fbd197fc 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -1,4 +1,3 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; @@ -8,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.d import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; import 'package:quick_log/quick_log.dart'; @@ -20,8 +20,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { var log = Logger('Symbol Instance Generator'); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is PBSharedInstanceIntermediateNode) { var method_signature = source.functionCallName?.pascalCase; if (method_signature == null) { @@ -107,8 +106,8 @@ class PBSymbolInstanceGenerator extends PBGenerator { return ''; } - assert(masterSymbol != null, - 'Could not find master symbol with UUID: $UUID'); + assert( + masterSymbol != null, 'Could not find master symbol with UUID: $UUID'); var buffer = StringBuffer(); buffer.write('${masterSymbol.friendlyName}(constraints, '); for (var ovrValue in overrideValues) { diff --git a/lib/generation/generators/symbols/pb_mastersym_gen.dart b/lib/generation/generators/symbols/pb_mastersym_gen.dart index a8787537..3253378f 100644 --- a/lib/generation/generators/symbols/pb_mastersym_gen.dart +++ b/lib/generation/generators/symbols/pb_mastersym_gen.dart @@ -1,8 +1,8 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:quick_log/quick_log.dart'; class PBMasterSymbolGenerator extends PBGenerator { @@ -10,8 +10,7 @@ class PBMasterSymbolGenerator extends PBGenerator { var log = Logger('Symbol Master Generator'); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { generatorContext.sizingContext = SizingValueContext.LayoutBuilderValue; var buffer = StringBuffer(); if (source is PBSharedMasterNode) { diff --git a/lib/generation/generators/symbols/pb_sym_mas_param_gen.dart b/lib/generation/generators/symbols/pb_sym_mas_param_gen.dart index ffab6fa4..feb333a6 100644 --- a/lib/generation/generators/symbols/pb_sym_mas_param_gen.dart +++ b/lib/generation/generators/symbols/pb_sym_mas_param_gen.dart @@ -1,14 +1,13 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBSymbolMasterParamGen extends PBGenerator { PBSymbolMasterParamGen() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { //TODO: is PBParam correct here? var name = (source as PBVariable).variableName; diff --git a/lib/generation/generators/util/topo_tree_iterator.dart b/lib/generation/generators/util/topo_tree_iterator.dart index 7a4af155..372b1e7e 100644 --- a/lib/generation/generators/util/topo_tree_iterator.dart +++ b/lib/generation/generators/util/topo_tree_iterator.dart @@ -27,13 +27,15 @@ class IntermediateTopoIterator } } - HashMap _inDegrees(List trees) { + HashMap _inDegrees(List items) { var inDegree = HashMap(); - trees.forEach((tree) { + items.forEach((tree) { inDegree.putIfAbsent(tree, () => 0); - tree.dependentsOn.forEach((dependent) { - inDegree.update(dependent, (value) => value + 1, ifAbsent: () => 1); - }); + var dependentOnIterator = tree.dependentOn; + while (dependentOnIterator.moveNext()) { + inDegree.update(dependentOnIterator.current, (value) => value + 1, + ifAbsent: () => 1); + } }); return inDegree; } @@ -54,13 +56,13 @@ class IntermediateTopoIterator var vertex = noInDegrees.first; noInDegrees.remove(vertex); ordered.add(vertex); - - vertex.dependentsOn.forEach((dependent) { - inDegrees[dependent] = inDegrees[dependent] - 1; - if (inDegrees[dependent] == 0) { - noInDegrees.add(dependent); + var it = vertex.dependentOn; + while (it.moveNext()) { + inDegrees[it.current] = inDegrees[it.current] - 1; + if (inDegrees[it.current] == 0) { + noInDegrees.add(it.current); } - }); + } } if (_detectCycle(inDegrees)) {} diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 9916dc14..518b1624 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -113,8 +113,11 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await setUpConfiguration(); pbProject.fileStructureStrategy = fileStructureStrategy; var trees = IntermediateTopoIterator(pbProject.forest); + while (trees.moveNext()) { var tree = trees.current; + tree.rootNode.currentContext.generationManager = generationManager; + tree.data.addImport('package:flutter/material.dart'); generationManager.data = tree.data; var fileName = tree.rootNode?.name?.snakeCase ?? 'no_name_found'; @@ -172,6 +175,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject); commandObservers.add(fileStructureStrategy); + fileStructureStrategy.addFileObserver(_importProcessor); // Execute command queue var queue = pbProject.genProjectData.commandQueue; @@ -183,18 +187,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await fileStructureStrategy.setUpDirectories(); } - //TODO delete - // void _commitImports( - // PBIntermediateNode node, String directoryName, String fileName) { - // var nodePaths = PBGenCache() - // .getPaths(node is PBSharedMasterNode ? node.SYMBOL_ID : node.UUID); - // var imports = {}; - // // Fetch imports for each path - // nodePaths.forEach( - // (path) => imports.addAll(ImportHelper.findImports(node, path))); - // imports.forEach(node.managerData.addImport); - // } - Future _commitDependencies(String projectName) async { var writer = pageWriter; if (writer is PBFlutterWriter) { diff --git a/lib/generation/generators/value_objects/generator_adapter.dart b/lib/generation/generators/value_objects/generator_adapter.dart index b90c6349..f56da049 100644 --- a/lib/generation/generators/value_objects/generator_adapter.dart +++ b/lib/generation/generators/value_objects/generator_adapter.dart @@ -1,13 +1,13 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; ///An Adapter that allows custom string to be injected into a generator instead of a [PBIntermediateNode] class StringGeneratorAdapter extends PBGenerator { final String overridenString; StringGeneratorAdapter(this.overridenString); @override - String generate(PBIntermediateNode source, GeneratorContext context) { + String generate(PBIntermediateNode source, PBContext context) { return overridenString; } } diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index a5cb626c..ccf3b2a8 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -1,8 +1,8 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:recase/recase.dart'; class BLoCStateTemplateStrategy extends TemplateStrategy { @@ -11,7 +11,7 @@ class BLoCStateTemplateStrategy extends TemplateStrategy { BLoCStateTemplateStrategy({this.isFirst, this.abstractClassName}); @override String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, - GeneratorContext generatorContext, + PBContext generatorContext, {args}) { var widgetName = retrieveNodeName(node); var returnStatement = node.generator.generate(node, generatorContext); diff --git a/lib/generation/generators/value_objects/template_strategy/empty_page_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/empty_page_template_strategy.dart index 10ceb5b3..f9e3fa5c 100644 --- a/lib/generation/generators/value_objects/template_strategy/empty_page_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/empty_page_template_strategy.dart @@ -1,12 +1,12 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class EmptyPageTemplateStrategy extends TemplateStrategy { @override String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, - GeneratorContext generatorContext, + PBContext generatorContext, {var args}) => args is String ? args : ''; } diff --git a/lib/generation/generators/value_objects/template_strategy/inline_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/inline_template_strategy.dart index d57f1b62..74eb3d6a 100644 --- a/lib/generation/generators/value_objects/template_strategy/inline_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/inline_template_strategy.dart @@ -1,12 +1,12 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class InlineTemplateStrategy extends TemplateStrategy { @override String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, - GeneratorContext generatorContext, + PBContext generatorContext, {var args}) { return node is String ? node diff --git a/lib/generation/generators/value_objects/template_strategy/pb_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/pb_template_strategy.dart index 40ca6631..4b104cb2 100644 --- a/lib/generation/generators/value_objects/template_strategy/pb_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/pb_template_strategy.dart @@ -1,11 +1,11 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; abstract class TemplateStrategy { String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, - GeneratorContext generatorContext, + PBContext generatorContext, {var args}); String retrieveNodeName(var node) { var formatter = (name) => PBInputFormatter.formatLabel(name, diff --git a/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart index 0b329d51..8d63380f 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart @@ -1,13 +1,13 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; ///Generating a [StatefulWidget] class StatefulTemplateStrategy extends TemplateStrategy { @override String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, - GeneratorContext generatorContext, + PBContext generatorContext, {args}) { var widgetName = retrieveNodeName(node); var constructorName = '$widgetName'; diff --git a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart index 04217c1c..82692712 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart @@ -1,14 +1,14 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:recase/recase.dart'; class StatelessTemplateStrategy extends TemplateStrategy { @override String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, - GeneratorContext generatorContext, + PBContext generatorContext, {args}) { var widgetName = node.name; var returnStatement = node.generator.generate(node, generatorContext); diff --git a/lib/generation/generators/visual-widgets/pb_align_gen.dart b/lib/generation/generators/visual-widgets/pb_align_gen.dart index 96ee3aa1..1ca3a22e 100644 --- a/lib/generation/generators/visual-widgets/pb_align_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_align_gen.dart @@ -1,8 +1,8 @@ import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:quick_log/quick_log.dart'; class PBAlignGenerator extends PBGenerator { @@ -10,8 +10,7 @@ class PBAlignGenerator extends PBGenerator { PBAlignGenerator() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is InjectedAlign) { var buffer = StringBuffer(); buffer.write('Align('); diff --git a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart index fd335e5c..c65b0d0e 100644 --- a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart @@ -1,10 +1,9 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBBitmapGenerator extends PBGenerator { var _sizehelper; @@ -14,8 +13,7 @@ class PBBitmapGenerator extends PBGenerator { } @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { var buffer = StringBuffer(); buffer.write('Image.asset('); diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index 60552e73..2678188d 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -1,9 +1,9 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class PBContainerGenerator extends PBGenerator { @@ -12,8 +12,7 @@ class PBContainerGenerator extends PBGenerator { PBContainerGenerator() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { var buffer = StringBuffer(); buffer.write('Container('); diff --git a/lib/generation/generators/visual-widgets/pb_flexible_gen.dart b/lib/generation/generators/visual-widgets/pb_flexible_gen.dart index 64d43caf..b41e73a8 100644 --- a/lib/generation/generators/visual-widgets/pb_flexible_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_flexible_gen.dart @@ -1,7 +1,7 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/flexible.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:quick_log/quick_log.dart'; class PBFlexibleGenerator extends PBGenerator { @@ -10,7 +10,7 @@ class PBFlexibleGenerator extends PBGenerator { @override String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + PBIntermediateNode source, PBContext generatorContext) { if (source is Flexible) { var buffer = StringBuffer(); buffer.write('Flexible('); diff --git a/lib/generation/generators/visual-widgets/pb_padding_gen.dart b/lib/generation/generators/visual-widgets/pb_padding_gen.dart index 413a9323..5b4f7c5e 100644 --- a/lib/generation/generators/visual-widgets/pb_padding_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_padding_gen.dart @@ -1,9 +1,9 @@ import 'dart:mirrors'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import '../pb_generator.dart'; class PBPaddingGen extends PBGenerator { @@ -23,8 +23,7 @@ class PBPaddingGen extends PBGenerator { } @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (generatorContext.sizingContext == SizingValueContext.AppBarChild) { source.child.currentContext = source.currentContext; return source.child.generator.generate(source.child, generatorContext); diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 36d5983b..780b8df8 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -1,8 +1,8 @@ import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:quick_log/quick_log.dart'; class PBPositionedGenerator extends PBGenerator { @@ -10,8 +10,7 @@ class PBPositionedGenerator extends PBGenerator { var log = Logger('Positioned Generator'); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is InjectedPositioned) { var buffer = StringBuffer(); buffer.write('Positioned('); diff --git a/lib/generation/generators/visual-widgets/pb_shape_group_gen.dart b/lib/generation/generators/visual-widgets/pb_shape_group_gen.dart index fc8418fd..d6261514 100644 --- a/lib/generation/generators/visual-widgets/pb_shape_group_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_shape_group_gen.dart @@ -1,8 +1,8 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBShapeGroupGen extends PBGenerator { var _sizehelper; @@ -11,8 +11,7 @@ class PBShapeGroupGen extends PBGenerator { } @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is InheritedShapeGroup) { var buffer = StringBuffer(); buffer.write( diff --git a/lib/generation/generators/visual-widgets/pb_spacer_gen.dart b/lib/generation/generators/visual-widgets/pb_spacer_gen.dart index 100026c8..3645c91b 100644 --- a/lib/generation/generators/visual-widgets/pb_spacer_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_spacer_gen.dart @@ -1,14 +1,14 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/spacer.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBSpacerGenerator extends PBGenerator { PBSpacerGenerator() : super(); @override String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + PBIntermediateNode source, PBContext generatorContext) { if (source is Spacer) { var buffer = StringBuffer(); buffer.write('Spacer('); diff --git a/lib/generation/generators/visual-widgets/pb_text_gen.dart b/lib/generation/generators/visual-widgets/pb_text_gen.dart index 4c95ff96..5627d21f 100644 --- a/lib/generation/generators/visual-widgets/pb_text_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_text_gen.dart @@ -1,16 +1,15 @@ import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBTextGen extends PBGenerator with PBColorMixin { PBTextGen() : super(); @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is InheritedText) { source.currentContext.project.genProjectData .addDependencies('auto_size_text', '^2.1.0'); diff --git a/lib/generation/prototyping/pb_prototype_gen.dart b/lib/generation/prototyping/pb_prototype_gen.dart index dc7bb764..0cd7adb6 100644 --- a/lib/generation/prototyping/pb_prototype_gen.dart +++ b/lib/generation/prototyping/pb_prototype_gen.dart @@ -1,8 +1,8 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBPrototypeGenerator extends PBGenerator { PrototypeNode prototypeNode; @@ -13,8 +13,7 @@ class PBPrototypeGenerator extends PBGenerator { } @override - String generate( - PBIntermediateNode source, GeneratorContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { var name = _storage.getPageNodeById(prototypeNode.destinationUUID)?.name; if (name != null && name.isNotEmpty) { return '''GestureDetector( diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 4cd5bab7..d15af685 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -9,12 +10,25 @@ class PBContext { Point screenTopLeftCorner, screenBottomRightCorner; PBIntermediateTree tree; PBProject project; + SizingValueContext sizingContext = SizingValueContext.PointValue; + + ///TODO: This is going to change to the [GenerationConfiguration]. + PBGenerationManager generationManager; PBGenerationViewData get managerData => tree?.data; PBContext(this.configuration, {this.tree}); void addDependent(PBIntermediateTree dependet) { - tree.dependentsOn.add(dependet); + if (dependet != null) { + tree.addDependent(dependet); + } } } + +enum SizingValueContext { + PointValue, + MediaQueryValue, + LayoutBuilderValue, + AppBarChild, +} diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index d0452fda..7e2b597a 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -8,12 +8,28 @@ enum TREE_TYPE { } class PBIntermediateTree { + TREE_TYPE tree_type = TREE_TYPE.SCREEN; PBGenerationViewData data; PBIntermediateNode rootNode; - List dependentsOn; + + /// List of [PBIntermediteTree]s that `this` depends on. + /// + /// In other words, `this` can not be generated until its [dependentsOn]s are generated. + Set _dependentsOn; + Iterator get dependentOn => + _dependentsOn.where((depedent) => depedent != null).iterator; + String name; PBIntermediateTree(this.name) { - dependentsOn = []; + _dependentsOn = {}; + } + + /// Adding [PBIntermediateTree] as a dependecy. + /// + /// The [dependent] or its [dependent.rootNode] can not be `null` + void addDependent(PBIntermediateTree dependent) { + if (dependent != null && dependent.rootNode != null) { + _dependentsOn.add(dependent); + } } - TREE_TYPE tree_type = TREE_TYPE.SCREEN; } diff --git a/test/lib/generation/generator_test.dart b/test/lib/generation/generator_test.dart index 41b1c878..f66972c0 100644 --- a/test/lib/generation/generator_test.dart +++ b/test/lib/generation/generator_test.dart @@ -1,5 +1,4 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; @@ -20,7 +19,7 @@ class MockInheritedText extends Mock implements InheritedText {} class MockManager extends Mock implements PBFlutterGenerator {} -class MockContext extends Mock implements GeneratorContext {} +class MockContext extends Mock implements PBContext {} class MockData extends Mock implements IntermediateAuxiliaryData {} @@ -85,8 +84,6 @@ void main() { mockManager = PBFlutterGenerator(ImportHelper()); mockGenerator = PBContainerGenerator(); - - mockGenerator.manager = mockManager; }); test('', () { diff --git a/test/lib/generation/import_test.dart b/test/lib/generation/import_test.dart index 4b05d11b..9f809249 100644 --- a/test/lib/generation/import_test.dart +++ b/test/lib/generation/import_test.dart @@ -49,11 +49,11 @@ void main() { var pbIntermeidateTrees = []; /// `tree1` is going to depend on `tree0` and `tree0` depends on `tree2`. - /// t0 + /// ?t0? /// / \ /// t1 t2 - tree1.dependentsOn.add(tree0); - tree0.dependentsOn.add(tree2); + tree1.addDependent(tree0); + tree0.addDependent(tree2); pbIntermeidateTrees.addAll([tree0, tree2, tree1]); var dependencyIterator = @@ -73,10 +73,10 @@ void main() { /// a cycle between all three [PBIntermediateTree]s /// t0 /// / \ - /// t1---->t2 - tree1.dependentsOn.add(tree0); - tree0.dependentsOn.add(tree2); - tree2.dependentsOn.add(tree2); + /// t1----?t2 + tree1.addDependent(tree0); + tree0.addDependent(tree2); + tree2.addDependent(tree2); pbIntermeidateTrees.addAll([tree0, tree2, tree1]); var dependencyIterator = diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index a082c94a..b6e7faf5 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -1,3 +1,4 @@ +import 'dart:collection'; import 'dart:io'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; @@ -74,7 +75,8 @@ void main() { when(intermediateTree.rootNode).thenReturn(scaffold); when(intermediateTree.name).thenReturn('testTree'); when(intermediateTree.data).thenReturn(PBGenerationViewData()); - when(intermediateTree.dependentsOn).thenReturn([]); + when(intermediateTree.dependentOn) + .thenReturn(HasNextIterator(null) as Iterator); when(project.projectName).thenReturn( '${Directory.current.path}/test/lib/output_services/temp2/'); From 35927414030eb59ec183fd623ac7110a150c95f7 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 18 May 2021 15:54:17 -0600 Subject: [PATCH 095/404] Added todo --- .../generation_configuration/pb_generation_configuration.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index d8db17b8..8044fca9 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -218,6 +218,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { PBPlatformOrientationLinkerService().getWhoNeedsAbstractInstance(); currentMap.forEach((screenName, platformsMap) { + // TODO: get imports from `_importProcessor` + // using the UUID extracted from `getPlatformOrientationData` var temp = PBPlatformOrientationLinkerService() .getPlatformOrientationData(screenName); From f1b157bdb4ad99b7076813c93f6ffd693a52c45c Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 18 May 2021 17:22:30 -0600 Subject: [PATCH 096/404] Fix typo --- lib/interpret_and_optimize/helpers/pb_context.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index d15af685..4b4c4302 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -19,9 +19,9 @@ class PBContext { PBContext(this.configuration, {this.tree}); - void addDependent(PBIntermediateTree dependet) { - if (dependet != null) { - tree.addDependent(dependet); + void addDependent(PBIntermediateTree dependent) { + if (dependent != null) { + tree.addDependent(dependent); } } } From bded7df6569e2446065e127b6178381202d2e1e0 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 18 May 2021 19:58:22 -0600 Subject: [PATCH 097/404] Added dynamic imports to platform instance builder --- .../flutter_project_builder.dart | 3 +- .../import_helper.dart | 1 + .../commands/export_platform_command.dart | 2 +- .../responsive_layout_builder_command.dart | 7 +- .../commands/write_screen_command.dart | 2 +- .../pb_generation_configuration.dart | 29 +++++-- ...platform_orientation_generation_mixin.dart | 49 ++++++++++-- .../helpers/pb_gen_cache.dart | 77 ++++++++++--------- 8 files changed, 115 insertions(+), 55 deletions(-) diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index 78f1eb6a..b8fbde97 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -127,9 +127,10 @@ class FlutterProjectBuilder { } } await Future.wait(PBStateManagementLinker().stateQueue, eagerError: true); + + await generationConfiguration.generateProject(mainTree); await generationConfiguration .generatePlatformAndOrientationInstance(mainTree); - await generationConfiguration.generateProject(mainTree); var l = File('${pathToFlutterProject}lib/main.dart').readAsLinesSync(); var s = File('${pathToFlutterProject}lib/main.dart') diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index c6c288da..3fd08983 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -64,6 +64,7 @@ class ImportHelper implements FileWriterObserver { if (imports.containsKey(UUID)) { return imports[UUID]; } + return null; } void addImport(String import, String UUID) { diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index feb2dafb..754e4c23 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -21,7 +21,7 @@ class ExportPlatformCommand extends NodeFileStructureCommand { var path = p.join( strategy.GENERATED_PROJECT_PATH, 'lib/screens/$folderName/', - platform.toString().toLowerCase(), + platform.toString().toLowerCase().replaceAll('platform.', ''), ); strategy.writeDataToFile(code, path, fileName); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 0d2a662a..8d392157 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -1,5 +1,5 @@ import 'dart:collection'; - +import 'package:path/path.dart' as p; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -45,7 +45,10 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { '''; strategy.writeDataToFile( - template, DIR_TO_RESPONSIVE_LAYOUT, NAME_TO_RESPONSIVE_LAYOUT); + template, + p.join(strategy.GENERATED_PROJECT_PATH, DIR_TO_RESPONSIVE_LAYOUT), + NAME_TO_RESPONSIVE_LAYOUT, + ); } String _generatePlatformWidgets(List platforms) { diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index d1b9c7de..833f6e79 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -7,7 +7,7 @@ class WriteScreenCommand extends NodeFileStructureCommand { String name; String relativePath; - final SCREEN_PATH = 'lib/screens'; + static final SCREEN_PATH = 'lib/screens'; WriteScreenCommand(this.name, this.relativePath, String code) : super(code); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index a679a392..0f07e5a5 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -23,6 +23,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; +import 'package:path/path.dart' as p; abstract class GenerationConfiguration with PBPlatformOrientationGeneration { FileStructureStrategy fileStructureStrategy; @@ -210,15 +211,31 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { PBPlatformOrientationLinkerService().getWhoNeedsAbstractInstance(); currentMap.forEach((screenName, platformsMap) { - // TODO: get imports from `_importProcessor` - // using the UUID extracted from `getPlatformOrientationData` - var temp = PBPlatformOrientationLinkerService() - .getPlatformOrientationData(screenName); + var rawImports = getPlatformImports(screenName); - print('hello'); - generatePlatformInstance(platformsMap, screenName, mainTree); + var newCommand = generatePlatformInstance( + platformsMap, screenName, mainTree, rawImports); + if (newCommand != null) { + commandObservers + .forEach((observer) => observer.commandCreated(newCommand)); + } _importProcessor; }); } + + Set getPlatformImports(String screenName) { + var platformOrientationMap = PBPlatformOrientationLinkerService() + .getPlatformOrientationData(screenName); + var imports = {}; + platformOrientationMap.forEach((key, map) { + map.forEach((key, tree) { + imports.add(_importProcessor.getImport( + p.basenameWithoutExtension(tree.rootNode.name.snakeCase))); + }); + }); + // TODO: add import to responsive layout builder + + return imports; + } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 4586639e..afc4e137 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -1,29 +1,46 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:recase/recase.dart'; +import 'package:path/path.dart' as p; mixin PBPlatformOrientationGeneration { - void generatePlatformInstance(Map> platformsMap, - String screenName, PBProject mainTree) { + NodeFileStructureCommand generatePlatformInstance( + Map> platformsMap, + String screenName, + PBProject mainTree, + Set rawImports) { var formatedName = screenName.snakeCase.toLowerCase(); + var cookedImports = _cookImports( + rawImports, + p.join( + mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH + + WriteScreenCommand.SCREEN_PATH + + '/$formatedName' + + '/${formatedName}_platform_builder.dart', + )); + if (platformsMap.length > 1) { - mainTree.genProjectData.commandQueue.add(WriteScreenCommand( + return WriteScreenCommand( formatedName + '_platform_builder.dart', formatedName, - _getPlatformInstance(platformsMap, screenName), - )); + _getPlatformInstance(platformsMap, screenName, cookedImports), + ); + } else { + return null; } } - String _getPlatformInstance( - Map> platformsMap, String screenName) { + String _getPlatformInstance(Map> platformsMap, + String screenName, Set cookedImports) { var className = screenName.pascalCase; - // TODO: add dynamic imports return ''' import 'package:flutter/material.dart'; import '../../widgets/responsive_layout_builder.dart'; + ${_serveImports(cookedImports)} class ${className}PlatformBuilder extends StatelessWidget { @override @@ -70,4 +87,20 @@ mixin PBPlatformOrientationGeneration { node.name += '_$orientation'; } } + + Set _cookImports(Set rawImports, String possiblePath) { + var result = {}; + rawImports.forEach((import) { + result.add(PBGenCache().getRelativePathFromPaths(possiblePath, import)); + }); + return result; + } + + String _serveImports(Set cookedImports) { + var result = ''; + cookedImports.forEach((import) { + result += 'import \'${import}\';\n'; + }); + return result; + } } diff --git a/lib/interpret_and_optimize/helpers/pb_gen_cache.dart b/lib/interpret_and_optimize/helpers/pb_gen_cache.dart index f015b827..2c161a23 100644 --- a/lib/interpret_and_optimize/helpers/pb_gen_cache.dart +++ b/lib/interpret_and_optimize/helpers/pb_gen_cache.dart @@ -43,50 +43,55 @@ class PBGenCache { } for (var targetPath in targetPaths) { - // Tokenize [filePath] and the path to the file of [doObjectId] - var filePathTokens = filePath.split('/') - ..removeLast() - ..removeAt(0); if (targetPath == filePath) { continue; } - var targetPathTokens = targetPath.split('/')..removeAt(0); - var targetFileName = targetPathTokens.removeLast(); - // Get rid of paths that are the same - while (min(filePathTokens.length, targetPathTokens.length) != 0 && - filePathTokens[0] == targetPathTokens[0]) { - filePathTokens.removeAt(0); - targetPathTokens.removeAt(0); - } + paths.add(getRelativePathFromPaths(filePath, targetPath)); + } + return paths; + } - // Case for when files are in the same folder - if (filePathTokens.isEmpty && targetPathTokens.isEmpty) { - paths.add('./$targetFileName'); - } - // Case for when backtracking is not needed to get to [targetPath] - else if (filePathTokens.isEmpty) { - var result = './'; - for (var folder in targetPathTokens) { - result = '$result$folder/'; - } - paths.add('$result$targetFileName'); + String getRelativePathFromPaths(String filePath, String targetPath) { + // Tokenize [filePath] and the path to the file of [doObjectId] + var filePathTokens = filePath.split('/') + ..removeLast() + ..removeAt(0); + + var targetPathTokens = targetPath.split('/')..removeAt(0); + var targetFileName = targetPathTokens.removeLast(); + // Get rid of paths that are the same + while (min(filePathTokens.length, targetPathTokens.length) != 0 && + filePathTokens[0] == targetPathTokens[0]) { + filePathTokens.removeAt(0); + targetPathTokens.removeAt(0); + } + + // Case for when files are in the same folder + if (filePathTokens.isEmpty && targetPathTokens.isEmpty) { + return './$targetFileName'; + } + // Case for when backtracking is not needed to get to [targetPath] + else if (filePathTokens.isEmpty) { + var result = './'; + for (var folder in targetPathTokens) { + result = '$result$folder/'; } - // Case for when backtracking is needed to get to [targetPath] - else { - var result = ''; + return '$result$targetFileName'; + } + // Case for when backtracking is needed to get to [targetPath] + else { + var result = ''; - // Backtrack - for (var i = 0; i < filePathTokens.length; i++) { - result = '$result../'; - } + // Backtrack + for (var i = 0; i < filePathTokens.length; i++) { + result = '$result../'; + } - // Add necessary folders - for (var i = 0; i < targetPathTokens.length; i++) { - result = '$result${targetPathTokens[i]}/'; - } - paths.add('$result$targetFileName'); + // Add necessary folders + for (var i = 0; i < targetPathTokens.length; i++) { + result = '$result${targetPathTokens[i]}/'; } + return '$result$targetFileName'; } - return paths; } } From 198c29c470af574da6eef2a125b19ea2f7486919 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Tue, 18 May 2021 18:59:32 -0700 Subject: [PATCH 098/404] Added maps for quicker lookup and now overrides work at first level --- .../pb_generator_context.dart | 3 + .../symbols/pb_instancesym_gen.dart | 79 ++++++++++--------- .../generators/symbols/pb_mastersym_gen.dart | 2 + .../entities/pb_shared_instance.dart | 14 ++-- .../entities/pb_shared_master_node.dart | 13 ++- 5 files changed, 58 insertions(+), 53 deletions(-) diff --git a/lib/generation/generators/attribute-helper/pb_generator_context.dart b/lib/generation/generators/attribute-helper/pb_generator_context.dart index d32e5ed9..1b338bff 100644 --- a/lib/generation/generators/attribute-helper/pb_generator_context.dart +++ b/lib/generation/generators/attribute-helper/pb_generator_context.dart @@ -1,6 +1,9 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; + /// This class is responsible for sharing contextual data needed throughout the generation process. Generators will pass this information to it's children. class GeneratorContext { SizingValueContext sizingContext = SizingValueContext.PointValue; + PBSharedMasterNode masterNode; GeneratorContext({ this.sizingContext, diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index c053d087..702421b1 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -49,45 +49,48 @@ class PBSymbolInstanceGenerator extends PBGenerator { buffer.write(method_signature); buffer.write('('); buffer.write('constraints,'); - - for (var param in source.sharedParamValues ?? []) { - switch (param.type) { - case PBSharedInstanceIntermediateNode: - var siString = genSymbolInstance( - param.UUID, - param.value, - source.overrideValues, - source.managerData - ); - if (siString != '') { - buffer.write('${param.name}: '); - buffer.write(siString); - } - break; - case InheritedBitmap: - buffer.write('${param.name}: \"assets/${param.value["_ref"]}\",'); - break; - case TextStyle: - // hack to include import - source.currentContext.treeRoot.data.addImport( - 'package:${MainInfo().projectName}/document/shared_props.g.dart'); - buffer.write( - '${param.name}: ${SharedStyle_UUIDToName[param.value]}.textStyle,'); - break; - case Style: - // hack to include import - source.currentContext.treeRoot.data.addImport( - 'package:${MainInfo().projectName}/document/shared_props.g.dart'); - buffer.write( - '${param.name}: ${SharedStyle_UUIDToName[param.value]},'); - break; - case String: - buffer.write('${param.name}: \"${param.value}\",'); - break; - default: - log.info('Unknown type ${param.type.toString()} in parameter values for symbol instance.\n'); + + // need to iterate through master symbol parametersDefsMap to pass parent variables down to children + var masterSymbol = getMasterSymbol(source.UUID); + masterSymbol.parametersDefsMap.forEach((overrideName, smParameter) { + var ovrValue = ''; + if (source.overrideValuesMap.containsKey(overrideName)) { + var param = source.overrideValuesMap[overrideName]; + switch (param.type) { + case PBSharedInstanceIntermediateNode: + ovrValue = genSymbolInstance( + param.UUID, + param.value, + source.overrideValues, + source.managerData + ); + break; + case InheritedBitmap: + ovrValue = '\"assets/${param.value["_ref"]}\",'; + break; + case TextStyle: + // hack to include import + source.currentContext.treeRoot.data.addImport( + 'package:${MainInfo().projectName}/document/shared_props.g.dart'); + ovrValue = '${SharedStyle_UUIDToName[param.value]}.textStyle,'; + break; + case Style: + // hack to include import + source.currentContext.treeRoot.data.addImport( + 'package:${MainInfo().projectName}/document/shared_props.g.dart'); + ovrValue = '${SharedStyle_UUIDToName[param.value]},'; + break; + case String: + ovrValue = '\"${param.value}\",'; + break; + default: + log.info('Unknown type ${param.type.toString()} in parameter values for symbol instance.\n'); + } + var friendlyName = SN_UUIDtoVarName[PBInputFormatter.findLastOf(smParameter.propertyName, '/')]; + buffer.write('$friendlyName: $ovrValue'); } - } + }); + // end of return function(); buffer.write(');\n'); // end of builder: (context, constraints) { diff --git a/lib/generation/generators/symbols/pb_mastersym_gen.dart b/lib/generation/generators/symbols/pb_mastersym_gen.dart index 463aa370..ba1d5984 100644 --- a/lib/generation/generators/symbols/pb_mastersym_gen.dart +++ b/lib/generation/generators/symbols/pb_mastersym_gen.dart @@ -19,12 +19,14 @@ class PBMasterSymbolGenerator extends PBGenerator { return ''; } // override styles if need be. + generatorContext.masterNode = source; source.child.currentContext = source.currentContext; // see if widget itself is overridden, need to pass var generatedWidget = source.child.generator.generate(source.child, generatorContext); + generatorContext.masterNode = null; if (generatedWidget == null || generatedWidget.isEmpty) { return ''; } diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 8d676433..10c6963d 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -38,8 +38,8 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode PrototypeNode prototypeNode; List overrideValues; - - Map sharedValuesMap = {}; + // quick lookup based on UUID_type + Map overrideValuesMap = {}; PBSharedInstanceIntermediateNode( this.originalRef, @@ -65,14 +65,12 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode generator = PBSymbolInstanceGenerator(); overrideValues = sharedParamValues - .map((v) => PBSymbolInstanceOverridableValue(v.UUID, v.value, v.type)) + .map((v) { + var symOvrValue = PBSymbolInstanceOverridableValue(v.UUID, v.value, v.type); + overrideValuesMap[v.overrideName] = symOvrValue; + return symOvrValue; }) .toList() ..removeWhere((v) => v == null || v.value == null); - - //for (var sharedParam in sharedParamValues) { - // sharedValuesMap[sharedParam.overrideName] = sharedParam; - //} - } @override diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index e7d5d381..b970616f 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -30,6 +30,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode final String SYMBOL_ID; List parametersDefinition; + Map parametersDefsMap = {}; ///The children that makes the UI of the [PBSharedMasterNode]. The children are going to be wrapped ///using a [TempGroupLayoutNode] as the root Node. @@ -46,7 +47,6 @@ class PBSharedMasterNode extends PBVisualIntermediateNode ///The properties that could be be overridable on a [PBSharedMasterNode] List overridableProperties; - Map overridePropMap = {}; String friendlyName; PBSharedMasterNode( @@ -89,7 +89,8 @@ class PBSharedMasterNode extends PBVisualIntermediateNode Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y); parametersDefinition = overridableProperties - .map((p) => PBSymbolMasterParameter( + .map((p) { + var PBSymMasterP = PBSymbolMasterParameter( p._friendlyName, p.type, p.UUID, @@ -101,14 +102,12 @@ class PBSharedMasterNode extends PBVisualIntermediateNode currentContext.screenTopLeftCorner.y, currentContext.screenBottomRightCorner.x, currentContext.screenBottomRightCorner.y, - context: currentContext)) + context: currentContext); + parametersDefsMap[p.propertyName] = PBSymMasterP; + return PBSymMasterP; }) .toList() ..removeWhere((p) => p == null || p.parameterDefinition == null); - // create quick lookup map for overridable properties by UUID - for (var override in overridableProperties) { - overridePropMap[override.UUID] = override; - } } @override From 9411ac32beb7b130b1ff3181f023323e1e5dfa3a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 18 May 2021 20:48:45 -0600 Subject: [PATCH 099/404] Update SAC submodule ref --- SketchAssetConverter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SketchAssetConverter b/SketchAssetConverter index 1b5f17f1..1b5effbd 160000 --- a/SketchAssetConverter +++ b/SketchAssetConverter @@ -1 +1 @@ -Subproject commit 1b5f17f1dc78d907082eada8eaa79b820908eccf +Subproject commit 1b5effbd220ff03015bc4b288184005e4443f056 From 89a7919498cabda56190a81baf53292d25f930d4 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 18 May 2021 21:10:36 -0600 Subject: [PATCH 100/404] Fix check-git.sh always saying SAC is out of date --- pb-scripts/check-git.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pb-scripts/check-git.sh b/pb-scripts/check-git.sh index be14bc2f..b576318e 100755 --- a/pb-scripts/check-git.sh +++ b/pb-scripts/check-git.sh @@ -19,8 +19,8 @@ then currentCom=`git rev-parse HEAD` echo "Downloading submodule SketchAssetConverter" else - masterCom=`git rev-parse @:./SketchAssetConverter` - # echo $masterCom + cd .. + masterCom=`git rev-parse @:SketchAssetConverter` if [ $masterCom == $currentCom ] then From beeabd86fd02c0ef6833815fae7995ec0fda4215 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 18 May 2021 22:43:14 -0600 Subject: [PATCH 101/404] Provider no longer generates final global vars --- .../state_management/provider_middleware.dart | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 6151a5bf..1a2901ed 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -1,10 +1,8 @@ import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; -import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; @@ -32,15 +30,6 @@ class ProviderMiddleware extends Middleware { .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); managerData.addImport('package:provider/provider.dart'); watcherName = getVariableName(node.name.snakeCase + '_notifier'); - var widgetName = node.functionCallName.camelCase; - var watcher; - - if (node.currentContext.treeRoot.rootNode.generator.templateStrategy - is StatelessTemplateStrategy) { - watcher = PBVariable(watcherName, 'final ', true, - '${getName(node.functionCallName).pascalCase}().${widgetName}'); - managerData.addGlobalVariable(watcher); - } addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); PBGenCache().appendToCache(node.SYMBOL_ID, From 473d13cf172e897e234e6b74a08b4ce58632f591 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Wed, 19 May 2021 16:27:15 -0600 Subject: [PATCH 102/404] Made it a requirement using UUIDs in commands, this allows for better retrival of a tree's dependency imports. Finally, made the topological iterator to throw an exception everytime there is a cycle in the graph, as the algorithm is not going to function with cycles --- .../generators/util/topo_tree_iterator.dart | 31 +++- .../commands/add_constant_command.dart | 4 +- .../commands/add_dependency_command.dart | 2 +- .../commands/export_platform_command.dart | 3 +- .../commands/file_structure_command.dart | 6 +- .../commands/node_file_structure_command.dart | 2 +- .../commands/orientation_builder_command.dart | 2 + .../responsive_layout_builder_command.dart | 2 + .../commands/write_screen_command.dart | 3 +- .../commands/write_symbol_command.dart | 2 +- .../pb_file_structure_strategy.dart | 15 +- .../pb_generation_configuration.dart | 3 + ...platform_orientation_generation_mixin.dart | 3 + .../helpers/pb_intermediate_node_tree.dart | 5 + ...b_platform_orientation_linker_service.dart | 9 +- .../commands/add_constant_command_test.dart | 4 +- .../commands/add_dependency_command_test.dart | 2 +- .../commands/write_screen_command_test.dart | 2 +- .../commands/write_symbol_command_test.dart | 2 +- test/lib/generation/import_test.dart | 136 +++++++++--------- 20 files changed, 141 insertions(+), 97 deletions(-) diff --git a/lib/generation/generators/util/topo_tree_iterator.dart b/lib/generation/generators/util/topo_tree_iterator.dart index 372b1e7e..cf2bd220 100644 --- a/lib/generation/generators/util/topo_tree_iterator.dart +++ b/lib/generation/generators/util/topo_tree_iterator.dart @@ -5,12 +5,16 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod ///Iterating through the screens in a manner where, the screens that are ///dependent are processed first. /// +/// Make sure there are no cycles in the graph. "In a dependency graph, +/// the cycles of dependencies (also called circular dependencies) lead to a situation in which no valid evaluation order exists, +/// because none of the objects in the cycle may be evaluated first." +/// * If cycles are detected in the list, then a [CyclicDependencyError] is going to be thrown. +/// ///For example, assyme we have the following dependency graph: -/// t0 -/// / \ -/// t1 t2 /// `tree1` is going to depend on `tree0` and `tree0` depends on `tree2`. -/// We should traverse the graph first processing `t1`, then `t0`, and finally `t2`. +/// t1 --> t0 --> t2 +/// The correct order should be: `[t2, t0, t1]`, +/// because t2 has dependets, therefore, it needs to be processed first. class IntermediateTopoIterator implements Iterator { List trees; @@ -24,6 +28,7 @@ class IntermediateTopoIterator trees = topologicalSort(trees); if (trees.isNotEmpty) { _currentElement = trees[0]; + trees = List.from(trees.reversed); } } @@ -65,7 +70,9 @@ class IntermediateTopoIterator } } - if (_detectCycle(inDegrees)) {} + if (_detectCycle(inDegrees)) { + throw CyclicDependencyError(trees); + } return ordered; } @@ -82,3 +89,17 @@ class IntermediateTopoIterator return false; } } + +/// Error thrown when there is a cycle in the dependency graph of [PBIntermediateTree] +class CyclicDependencyError extends Error { + List items; + CyclicDependencyError([this.items]); + @override + String toString() { + var message = 'Cycle Detected on Graph'; + if (items != null) { + message += '. Graph: ${items.toString()}'; + } + return message; + } +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index acefeff6..ad534966 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -1,4 +1,3 @@ -import 'dart:ffi'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; @@ -12,7 +11,8 @@ class AddConstantCommand extends FileStructureCommand { final String CONST_DIR_PATH = 'lib/constants/'; final String CONST_FILE_NAME = 'constants.dart'; - AddConstantCommand(this.name, this.type, this.value); + AddConstantCommand(String UUID, this.name, this.type, this.value) + : super(UUID); /// Adds a constant containing `type`, `name` and `value` to `constants.dart` file @override diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart index 5a48aad5..a3ad3933 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -14,7 +14,7 @@ class AddDependencyCommand extends FileStructureCommand { /// The version of [package] String version; - AddDependencyCommand(this.package, this.version); + AddDependencyCommand(String UUID, this.package, this.version) : super(UUID); /// Appends `package` and `version` to `pubspec.yaml` dependencies. @override diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index feb2dafb..a94aa4e4 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -10,11 +10,12 @@ class ExportPlatformCommand extends NodeFileStructureCommand { String folderName; ExportPlatformCommand( + String UUID, this.platform, this.folderName, this.fileName, String code, - ) : super(code); + ) : super(UUID, code); @override Future write(FileStructureStrategy strategy) async { diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart index df421e60..7800c06b 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart @@ -1,8 +1,10 @@ -import 'dart:io'; - import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; abstract class FileStructureCommand { + final String UUID; + + FileStructureCommand(this.UUID); + /// Method that executes the [FileStructureCommand]'s action. Future write(FileStructureStrategy strategy); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart index 60389f29..10e6a87b 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart @@ -3,5 +3,5 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure /// Class that relies on `code` to implement its `write` method. abstract class NodeFileStructureCommand extends FileStructureCommand { String code; - NodeFileStructureCommand(this.code); + NodeFileStructureCommand(String UUID, this.code) : super(UUID); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart index d5123f49..3145b067 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart @@ -6,6 +6,8 @@ class OrientationBuilderCommand extends FileStructureCommand { final DIR_TO_ORIENTATION_BUILDER = 'lib/widgets/'; final NAME_TO_ORIENTAION_BUILDER = 'responsive_orientation_builder.dart'; + OrientationBuilderCommand(String UUID) : super(UUID); + @override Future write(FileStructureStrategy strategy) { var template = ''' diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 0d2a662a..0b368c0b 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -9,6 +9,8 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { final DIR_TO_RESPONSIVE_LAYOUT = 'lib/widgets/'; final NAME_TO_RESPONSIVE_LAYOUT = 'responsive_layout_builder.dart'; + ResponsiveLayoutBuilderCommand(String UUID) : super(UUID); + @override Future write(FileStructureStrategy strategy) async { var platforms = PBPlatformOrientationLinkerService() diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index d1b9c7de..9f64ad32 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -9,7 +9,8 @@ class WriteScreenCommand extends NodeFileStructureCommand { final SCREEN_PATH = 'lib/screens'; - WriteScreenCommand(this.name, this.relativePath, String code) : super(code); + WriteScreenCommand(String UUID, this.name, this.relativePath, String code) + : super(UUID, code); /// Writes a screen file containing [code] to [path] with [name] as its filename. /// diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index ba39b402..5b7914a2 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -7,7 +7,7 @@ class WriteSymbolCommand extends NodeFileStructureCommand { String name; final String SYMBOL_PATH = 'lib/widgets'; - WriteSymbolCommand(this.name, String code) : super(code); + WriteSymbolCommand(String UUID, this.name, String code) : super(UUID, code); /// Writes a symbol file containing [data] with [name] as its filename. /// diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 809d6c01..a70fe6fb 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -43,7 +43,7 @@ abstract class FileStructureStrategy implements CommandInvoker { /// ///A good example of an observer is the [ImportHelper], which keeps track ///of the files relative location to handle their imports. - final List _fileObservers = []; + final List fileObservers = []; ///Indicator that signals if the required directories are constructed. /// @@ -60,7 +60,7 @@ abstract class FileStructureStrategy implements CommandInvoker { void addFileObserver(FileWriterObserver observer) { if (observer != null) { - _fileObservers.add(observer); + fileObservers.add(observer); } } @@ -119,8 +119,7 @@ abstract class FileStructureStrategy implements CommandInvoker { return Future.value(); } - String getViewPath(String fileName) => - '$_viewDirectoryPath$fileName.dart'; + String getViewPath(String fileName) => '$_viewDirectoryPath$fileName.dart'; @override void commandCreated(FileStructureCommand command) { @@ -139,11 +138,11 @@ abstract class FileStructureStrategy implements CommandInvoker { /// [FileWriterObserver]s are going to be notfied of the new created file. void writeDataToFile(String data, String directory, String name, {String UUID}) { - var file = _getFile(directory, name); + var file = getFile(directory, name); file.createSync(recursive: true); file.writeAsStringSync(data); - _fileObservers.forEach((observer) => observer.fileCreated( + fileObservers.forEach((observer) => observer.fileCreated( file.path, UUID ?? p.basenameWithoutExtension(file.path))); } @@ -156,7 +155,7 @@ abstract class FileStructureStrategy implements CommandInvoker { /// [ModFile] function is found, its going to append the information at the end of the lines void appendDataToFile(ModFile modFile, String directory, String name, {String UUID, bool createFileIfNotFound = true}) { - var file = _getFile(directory, name); + var file = getFile(directory, name); if (file.existsSync()) { var fileLines = file.readAsLinesSync(); var modLines = modFile(fileLines); @@ -169,7 +168,7 @@ abstract class FileStructureStrategy implements CommandInvoker { } } - File _getFile(String directory, String name) => File(p.join(directory, name)); + File getFile(String directory, String name) => File(p.join(directory, name)); } /// [Function] that returns the modified [lines] that should make the new data. diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 518b1624..37fa33eb 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -141,6 +141,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(ExportPlatformCommand( + tree.UUID, tree.rootNode.currentContext.tree.data.platform, '$fileName', '$fileName${getPlatformOrientationName(tree.rootNode)}.dart', @@ -149,6 +150,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } else if (tree.rootNode is InheritedScaffold) { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(WriteScreenCommand( + tree.UUID, '$fileName.dart', '${tree.name}', generationManager.generate(tree.rootNode), @@ -156,6 +158,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } else { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(WriteSymbolCommand( + tree.UUID, '$fileName.dart', generationManager.generate(tree.rootNode), )); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 1a7f6ca2..7d926d4a 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:recase/recase.dart'; +import 'package:uuid/uuid.dart'; mixin PBPlatformOrientationGeneration { void generatePlatformInstance(Map> platformsMap, @@ -14,6 +15,7 @@ mixin PBPlatformOrientationGeneration { } if (platformsMap.length > 1) { mainTree.genProjectData.commandQueue.add(WriteScreenCommand( + Uuid().v4(), formatedName + '_platform_builder.dart', formatedName, _getPlatformInstance(platformsMap, screenName), @@ -25,6 +27,7 @@ mixin PBPlatformOrientationGeneration { void _generateOrientationInstance(String screenName, PBProject mainTree) { var formatedName = screenName.snakeCase.toLowerCase(); mainTree.genProjectData.commandQueue.add(WriteScreenCommand( + Uuid().v4(), formatedName + '_orientation_builder.dart', formatedName, _getOrientationInstance(screenName), diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 7e2b597a..d5708cda 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:uuid/uuid.dart'; enum TREE_TYPE { MISC, @@ -8,6 +9,9 @@ enum TREE_TYPE { } class PBIntermediateTree { + String _UUID; + String get UUID => _UUID; + TREE_TYPE tree_type = TREE_TYPE.SCREEN; PBGenerationViewData data; PBIntermediateNode rootNode; @@ -22,6 +26,7 @@ class PBIntermediateTree { String name; PBIntermediateTree(this.name) { _dependentsOn = {}; + _UUID = Uuid().v4(); } /// Adding [PBIntermediateTree] as a dependecy. diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 4a3bb12b..28565897 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -40,13 +40,13 @@ class PBPlatformOrientationLinkerService { // if there are more than 1 orientation on the project if (hasMultipleOrientations()) { tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(OrientationBuilderCommand()); + .add(OrientationBuilderCommand(tree.UUID)); } // Add responsive layout builder template to the project // if there are more than 1 plataform on the project if (hasMultiplePlatforms()) { tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(ResponsiveLayoutBuilderCommand()); + .add(ResponsiveLayoutBuilderCommand(tree.UUID)); _addBreakpoints(tree); } @@ -205,9 +205,10 @@ class PBPlatformOrientationLinkerService { void _addBreakpoints(PBIntermediateTree tree) { if (MainInfo().configurations.containsKey('breakpoints')) { - Map bp = MainInfo().configurations['breakpoints'].cast(); + Map bp = + MainInfo().configurations['breakpoints'].cast(); bp.forEach((key, value) { - var cmd = AddConstantCommand(key, 'num', value.toString()); + var cmd = AddConstantCommand(tree.UUID, key, 'num', value.toString()); tree.rootNode.currentContext.project.genProjectData.commandQueue .add(cmd); }); diff --git a/test/lib/generation/commands/add_constant_command_test.dart b/test/lib/generation/commands/add_constant_command_test.dart index 53a4c04d..55ddc99f 100644 --- a/test/lib/generation/commands/add_constant_command_test.dart +++ b/test/lib/generation/commands/add_constant_command_test.dart @@ -19,8 +19,8 @@ void main() { setUp(() { strategy = MockFSStrategy(); - const1 = AddConstantCommand(const1V[0], const1V[1], const1V[2]); - const2 = AddConstantCommand(const2V[0], const2V[1], const2V[2]); + const1 = AddConstantCommand('UUID', const1V[0], const1V[1], const1V[2]); + const2 = AddConstantCommand('UUID', const2V[0], const2V[1], const2V[2]); when(strategy.GENERATED_PROJECT_PATH).thenReturn('temp/'); }); test('Testing Adding Constants To Project', () async { diff --git a/test/lib/generation/commands/add_dependency_command_test.dart b/test/lib/generation/commands/add_dependency_command_test.dart index d673e5db..e1afe79c 100644 --- a/test/lib/generation/commands/add_dependency_command_test.dart +++ b/test/lib/generation/commands/add_dependency_command_test.dart @@ -19,7 +19,7 @@ void main() { setUp(() { package = 'auto_size_text'; version = '^2.1.0'; - command = AddDependencyCommand(package, version); + command = AddDependencyCommand('UUID', package, version); strategy = MockFSStrategy(); }); diff --git a/test/lib/generation/commands/write_screen_command_test.dart b/test/lib/generation/commands/write_screen_command_test.dart index 230e18d7..da3f9755 100644 --- a/test/lib/generation/commands/write_screen_command_test.dart +++ b/test/lib/generation/commands/write_screen_command_test.dart @@ -40,7 +40,7 @@ void main() { FileStructureStrategy strategy; setUp(() { - command = WriteScreenCommand('test_screen.dart', '', screenData); + command = WriteScreenCommand('UUID', 'test_screen.dart', '', screenData); strategy = MockFSStrategy(); when(strategy.GENERATED_PROJECT_PATH).thenReturn('temp/'); }); diff --git a/test/lib/generation/commands/write_symbol_command_test.dart b/test/lib/generation/commands/write_symbol_command_test.dart index 25a4018d..c43d7e42 100644 --- a/test/lib/generation/commands/write_symbol_command_test.dart +++ b/test/lib/generation/commands/write_symbol_command_test.dart @@ -31,7 +31,7 @@ void main() { FileStructureStrategy strategy; setUp(() { - command = WriteSymbolCommand('test_symbol.dart', symData); + command = WriteSymbolCommand('UUID', 'test_symbol.dart', symData); strategy = MockFSStrategy(); when(strategy.GENERATED_PROJECT_PATH).thenReturn('temp/'); }); diff --git a/test/lib/generation/import_test.dart b/test/lib/generation/import_test.dart index 9f809249..0ebfd92a 100644 --- a/test/lib/generation/import_test.dart +++ b/test/lib/generation/import_test.dart @@ -1,47 +1,40 @@ +import 'dart:io'; + import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/util/topo_tree_iterator.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:test/test.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; class NodeMock extends Mock implements PBIntermediateNode {} -void main() { - // Will test IntermediateNode that needs imports - // and an IntermediateNode without imports - var iNodeWithImports, iNodeWithoutImports; +class FileStructureStrategyMock extends Mock implements FileStructureStrategy {} - /// Three intermediateNodes that will generate import - var importee1, importee2, importee3; - var genCache; +class FileMock extends Mock implements File {} - PBIntermediateTree tree0, tree1, tree2; - group('Import test', () { +void main() { + group('[PBIntermediateTree] process order test', () { + PBIntermediateTree tree0, tree1, tree2; setUp(() { - iNodeWithImports = NodeMock(); - iNodeWithoutImports = NodeMock(); - importee1 = NodeMock(); - importee2 = NodeMock(); - importee3 = NodeMock(); - genCache = PBGenCache(); - tree0 = PBIntermediateTree('Tree0'); - tree1 = PBIntermediateTree('Tree1'); - tree2 = PBIntermediateTree('Tree2'); + tree0.rootNode = NodeMock(); + when(tree0.rootNode.UUID).thenReturn('00-00-01'); + when(tree0.rootNode.name).thenReturn('Tree0'); - when(iNodeWithImports.UUID).thenReturn('00-00-00'); - when(iNodeWithoutImports.UUID).thenReturn('00-01-00'); - when(importee1.UUID).thenReturn('00-00-01'); - when(importee2.UUID).thenReturn('00-00-02'); - when(importee3.UUID).thenReturn('00-00-03'); + tree1 = PBIntermediateTree('Tree1'); + tree1.rootNode = NodeMock(); + when(tree1.rootNode.UUID).thenReturn('00-00-02'); + when(tree1.rootNode.name).thenReturn('Tree1'); - when(iNodeWithImports.child).thenReturn(importee1); - when(importee1.child).thenReturn(importee2); - when(importee2.child).thenReturn(importee3); + tree2 = PBIntermediateTree('Tree2'); + tree2.rootNode = NodeMock(); + when(tree2.rootNode.UUID).thenReturn('00-00-03'); + when(tree2.rootNode.name).thenReturn('Tree2'); }); - test('Testing how [PBIntermediateTree] are processed.', () { ///[PBIntermediateTree]s that are going to be generated. The treees inside of the list ///are dependent on each other, therefore, to ensure import availability, trees need to @@ -49,18 +42,22 @@ void main() { var pbIntermeidateTrees = []; /// `tree1` is going to depend on `tree0` and `tree0` depends on `tree2`. - /// ?t0? - /// / \ - /// t1 t2 + /// t1 --> t0 --> t2 + /// The correct order should be: `[t2, t0, t1]`, + /// because t2 has dependets, therefore, it needs to be processed first. tree1.addDependent(tree0); tree0.addDependent(tree2); + + //The initial order should't manner the end result pbIntermeidateTrees.addAll([tree0, tree2, tree1]); var dependencyIterator = IntermediateTopoIterator(pbIntermeidateTrees); - var correctOrder = [tree1, tree0, tree2].iterator; + var correctOrder = [tree2, tree0, tree1].iterator; while (dependencyIterator.moveNext() && correctOrder.moveNext()) { - expect(dependencyIterator.current == correctOrder.current, true); + expect(dependencyIterator.current == correctOrder.current, true, + reason: + 'The [PBIntermediateTree]s are not being processed in the correct order in respect to their dependencies'); } }); @@ -71,45 +68,52 @@ void main() { var pbIntermeidateTrees = []; /// a cycle between all three [PBIntermediateTree]s - /// t0 - /// / \ - /// t1----?t2 + /// + /// + /// `tree1` --> `tree0` --> `tree2` + /// <\ / + /// ---------- tree1.addDependent(tree0); tree0.addDependent(tree2); - tree2.addDependent(tree2); + tree0.addDependent(tree1); pbIntermeidateTrees.addAll([tree0, tree2, tree1]); - var dependencyIterator = - IntermediateTopoIterator(pbIntermeidateTrees); - var correctOrder = [tree1, tree0, tree2].iterator; - while (dependencyIterator.moveNext() && correctOrder.moveNext()) { - expect(dependencyIterator.current == correctOrder.current, true); - } + expect( + () => + IntermediateTopoIterator(pbIntermeidateTrees), + throwsA(isA()), + reason: + '[CyclicDependencyError] is not being thrown when there is a cycle in the graph'); }); - - test('Testing import generation when imports are generated', () { - //Add symbol in the same folder as importer - genCache.setPathToCache(importee1.UUID, '/path/to/page/importee1.dart'); - //Add symbol located a directory above importer - genCache.setPathToCache(importee2.UUID, '/path/to/importee2.dart'); - //Add symbol located a directory below importer - genCache.setPathToCache( - importee3.UUID, '/path/to/page/sub/importee3.dart'); - - // Find the imports of importer.dart - var imports = ImportHelper.findImports( - iNodeWithImports, '/path/to/page/importer.dart'); - - expect(imports.length, 3); - expect(imports.contains('./importee1.dart'), true); - expect(imports.contains('../importee2.dart'), true); - expect(imports.contains('./sub/importee3.dart'), true); + }); + group('Import paths extraction test', () { + FileStructureStrategy _fileStructureStrategy; + ImportHelper importHelper; + var completePath = + 'desktop/project/lib/screens/homescreen/some_dart_page.dart'; + var genPath = 'desktop/project/'; + setUp(() { + _fileStructureStrategy = FileStructureStrategyMock(); + importHelper = ImportHelper(); + + when(_fileStructureStrategy.writeDataToFile(any, any, any)) + .thenAnswer((invocation) { + var dir = invocation.positionalArguments[1]; + var name = invocation.positionalArguments[2]; + var uuid = invocation.namedArguments['UUID'] ?? 'UUID'; + importHelper.fileCreated( + FlutterFileStructureStrategy(genPath, null, null) + .getFile(dir, name) + .path, + uuid); + }); + when(_fileStructureStrategy.GENERATED_PROJECT_PATH).thenReturn(genPath); }); - - test('Testing import generation when no imports are generated', () { - var noImports = ImportHelper.findImports( - iNodeWithoutImports, '/path/to/page/not_importer.dart'); - expect(noImports.length, 0); + test('Testing import generation when imports are generated', () { + var command = WriteScreenCommand( + 'UUID', 'some_dart_page.dart', 'homescreen/', 'dummy code'); + command.write(_fileStructureStrategy); + expect(importHelper.getImport('UUID'), completePath); }); }); } From 026558dc7627010c28bb320c1516f4345fd566b7 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 20 May 2021 14:30:47 -0600 Subject: [PATCH 103/404] Commands passing UUID to FileStructureStrategy. This is done to add the key correctly to the ImportHelper. --- .../file_structure_strategy/commands/write_screen_command.dart | 2 +- .../file_structure_strategy/commands/write_symbol_command.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 9f64ad32..22f5c8e1 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -19,7 +19,7 @@ class WriteScreenCommand extends NodeFileStructureCommand { Future write(FileStructureStrategy strategy) { var absPath = p.join(strategy.GENERATED_PROJECT_PATH, SCREEN_PATH, relativePath); - strategy.writeDataToFile(code, absPath, name); + strategy.writeDataToFile(code, absPath, name, UUID: UUID); return Future.value(p.join(absPath, name)); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 5ace30cd..0f627a26 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -23,7 +23,7 @@ class WriteSymbolCommand extends NodeFileStructureCommand { absPath = p.join(strategy.GENERATED_PROJECT_PATH, SYMBOL_PATH, relativePath); } - strategy.writeDataToFile(code, absPath, name); + strategy.writeDataToFile(code, absPath, name, UUID: UUID); return Future.value(p.join(absPath, name)); } } From 001872008054e79559ec9607c78f676cfb092618 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 20 May 2021 14:55:20 -0600 Subject: [PATCH 104/404] Merge branch 'feat/405-imports' into feat/424-dynamic-class-names --- .../generators/util/topo_tree_iterator.dart | 31 +++- .../commands/add_constant_command.dart | 4 +- .../commands/add_dependency_command.dart | 2 +- .../commands/export_platform_command.dart | 3 +- .../commands/file_structure_command.dart | 6 +- .../commands/node_file_structure_command.dart | 2 +- .../commands/orientation_builder_command.dart | 2 + .../responsive_layout_builder_command.dart | 2 + .../commands/write_screen_command.dart | 3 +- .../commands/write_symbol_command.dart | 2 +- .../pb_file_structure_strategy.dart | 15 +- .../pb_generation_configuration.dart | 3 + ...platform_orientation_generation_mixin.dart | 3 +- .../helpers/pb_intermediate_node_tree.dart | 5 + ...b_platform_orientation_linker_service.dart | 6 +- .../commands/add_constant_command_test.dart | 4 +- .../commands/add_dependency_command_test.dart | 2 +- .../commands/write_screen_command_test.dart | 2 +- .../commands/write_symbol_command_test.dart | 2 +- test/lib/generation/import_test.dart | 136 +++++++++--------- 20 files changed, 138 insertions(+), 97 deletions(-) diff --git a/lib/generation/generators/util/topo_tree_iterator.dart b/lib/generation/generators/util/topo_tree_iterator.dart index 372b1e7e..cf2bd220 100644 --- a/lib/generation/generators/util/topo_tree_iterator.dart +++ b/lib/generation/generators/util/topo_tree_iterator.dart @@ -5,12 +5,16 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod ///Iterating through the screens in a manner where, the screens that are ///dependent are processed first. /// +/// Make sure there are no cycles in the graph. "In a dependency graph, +/// the cycles of dependencies (also called circular dependencies) lead to a situation in which no valid evaluation order exists, +/// because none of the objects in the cycle may be evaluated first." +/// * If cycles are detected in the list, then a [CyclicDependencyError] is going to be thrown. +/// ///For example, assyme we have the following dependency graph: -/// t0 -/// / \ -/// t1 t2 /// `tree1` is going to depend on `tree0` and `tree0` depends on `tree2`. -/// We should traverse the graph first processing `t1`, then `t0`, and finally `t2`. +/// t1 --> t0 --> t2 +/// The correct order should be: `[t2, t0, t1]`, +/// because t2 has dependets, therefore, it needs to be processed first. class IntermediateTopoIterator implements Iterator { List trees; @@ -24,6 +28,7 @@ class IntermediateTopoIterator trees = topologicalSort(trees); if (trees.isNotEmpty) { _currentElement = trees[0]; + trees = List.from(trees.reversed); } } @@ -65,7 +70,9 @@ class IntermediateTopoIterator } } - if (_detectCycle(inDegrees)) {} + if (_detectCycle(inDegrees)) { + throw CyclicDependencyError(trees); + } return ordered; } @@ -82,3 +89,17 @@ class IntermediateTopoIterator return false; } } + +/// Error thrown when there is a cycle in the dependency graph of [PBIntermediateTree] +class CyclicDependencyError extends Error { + List items; + CyclicDependencyError([this.items]); + @override + String toString() { + var message = 'Cycle Detected on Graph'; + if (items != null) { + message += '. Graph: ${items.toString()}'; + } + return message; + } +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index acefeff6..ad534966 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -1,4 +1,3 @@ -import 'dart:ffi'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; @@ -12,7 +11,8 @@ class AddConstantCommand extends FileStructureCommand { final String CONST_DIR_PATH = 'lib/constants/'; final String CONST_FILE_NAME = 'constants.dart'; - AddConstantCommand(this.name, this.type, this.value); + AddConstantCommand(String UUID, this.name, this.type, this.value) + : super(UUID); /// Adds a constant containing `type`, `name` and `value` to `constants.dart` file @override diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart index 5a48aad5..a3ad3933 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -14,7 +14,7 @@ class AddDependencyCommand extends FileStructureCommand { /// The version of [package] String version; - AddDependencyCommand(this.package, this.version); + AddDependencyCommand(String UUID, this.package, this.version) : super(UUID); /// Appends `package` and `version` to `pubspec.yaml` dependencies. @override diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index 754e4c23..d8b96223 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -10,11 +10,12 @@ class ExportPlatformCommand extends NodeFileStructureCommand { String folderName; ExportPlatformCommand( + String UUID, this.platform, this.folderName, this.fileName, String code, - ) : super(code); + ) : super(UUID, code); @override Future write(FileStructureStrategy strategy) async { diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart index df421e60..7800c06b 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart @@ -1,8 +1,10 @@ -import 'dart:io'; - import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; abstract class FileStructureCommand { + final String UUID; + + FileStructureCommand(this.UUID); + /// Method that executes the [FileStructureCommand]'s action. Future write(FileStructureStrategy strategy); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart index 60389f29..10e6a87b 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart @@ -3,5 +3,5 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure /// Class that relies on `code` to implement its `write` method. abstract class NodeFileStructureCommand extends FileStructureCommand { String code; - NodeFileStructureCommand(this.code); + NodeFileStructureCommand(String UUID, this.code) : super(UUID); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart index d5123f49..3145b067 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart @@ -6,6 +6,8 @@ class OrientationBuilderCommand extends FileStructureCommand { final DIR_TO_ORIENTATION_BUILDER = 'lib/widgets/'; final NAME_TO_ORIENTAION_BUILDER = 'responsive_orientation_builder.dart'; + OrientationBuilderCommand(String UUID) : super(UUID); + @override Future write(FileStructureStrategy strategy) { var template = ''' diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 8d392157..b08d436c 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -9,6 +9,8 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { final DIR_TO_RESPONSIVE_LAYOUT = 'lib/widgets/'; final NAME_TO_RESPONSIVE_LAYOUT = 'responsive_layout_builder.dart'; + ResponsiveLayoutBuilderCommand(String UUID) : super(UUID); + @override Future write(FileStructureStrategy strategy) async { var platforms = PBPlatformOrientationLinkerService() diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 833f6e79..ec17c138 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -9,7 +9,8 @@ class WriteScreenCommand extends NodeFileStructureCommand { static final SCREEN_PATH = 'lib/screens'; - WriteScreenCommand(this.name, this.relativePath, String code) : super(code); + WriteScreenCommand(String UUID, this.name, this.relativePath, String code) + : super(UUID, code); /// Writes a screen file containing [code] to [path] with [name] as its filename. /// diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index ba39b402..5b7914a2 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -7,7 +7,7 @@ class WriteSymbolCommand extends NodeFileStructureCommand { String name; final String SYMBOL_PATH = 'lib/widgets'; - WriteSymbolCommand(this.name, String code) : super(code); + WriteSymbolCommand(String UUID, this.name, String code) : super(UUID, code); /// Writes a symbol file containing [data] with [name] as its filename. /// diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 809d6c01..a70fe6fb 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -43,7 +43,7 @@ abstract class FileStructureStrategy implements CommandInvoker { /// ///A good example of an observer is the [ImportHelper], which keeps track ///of the files relative location to handle their imports. - final List _fileObservers = []; + final List fileObservers = []; ///Indicator that signals if the required directories are constructed. /// @@ -60,7 +60,7 @@ abstract class FileStructureStrategy implements CommandInvoker { void addFileObserver(FileWriterObserver observer) { if (observer != null) { - _fileObservers.add(observer); + fileObservers.add(observer); } } @@ -119,8 +119,7 @@ abstract class FileStructureStrategy implements CommandInvoker { return Future.value(); } - String getViewPath(String fileName) => - '$_viewDirectoryPath$fileName.dart'; + String getViewPath(String fileName) => '$_viewDirectoryPath$fileName.dart'; @override void commandCreated(FileStructureCommand command) { @@ -139,11 +138,11 @@ abstract class FileStructureStrategy implements CommandInvoker { /// [FileWriterObserver]s are going to be notfied of the new created file. void writeDataToFile(String data, String directory, String name, {String UUID}) { - var file = _getFile(directory, name); + var file = getFile(directory, name); file.createSync(recursive: true); file.writeAsStringSync(data); - _fileObservers.forEach((observer) => observer.fileCreated( + fileObservers.forEach((observer) => observer.fileCreated( file.path, UUID ?? p.basenameWithoutExtension(file.path))); } @@ -156,7 +155,7 @@ abstract class FileStructureStrategy implements CommandInvoker { /// [ModFile] function is found, its going to append the information at the end of the lines void appendDataToFile(ModFile modFile, String directory, String name, {String UUID, bool createFileIfNotFound = true}) { - var file = _getFile(directory, name); + var file = getFile(directory, name); if (file.existsSync()) { var fileLines = file.readAsLinesSync(); var modLines = modFile(fileLines); @@ -169,7 +168,7 @@ abstract class FileStructureStrategy implements CommandInvoker { } } - File _getFile(String directory, String name) => File(p.join(directory, name)); + File getFile(String directory, String name) => File(p.join(directory, name)); } /// [Function] that returns the modified [lines] that should make the new data. diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 0f07e5a5..6c91b848 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -143,6 +143,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { getPlatformOrientationName(tree.rootNode); tree.rootNode.currentContext.project.genProjectData.commandQueue .add(ExportPlatformCommand( + tree.UUID, tree.rootNode.currentContext.tree.data.platform, '$fileName', '${tree.rootNode.name.snakeCase}.dart', @@ -151,6 +152,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } else if (tree.rootNode is InheritedScaffold) { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(WriteScreenCommand( + tree.UUID, '$fileName.dart', '${tree.name}', generationManager.generate(tree.rootNode), @@ -158,6 +160,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } else { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(WriteSymbolCommand( + tree.UUID, '$fileName.dart', generationManager.generate(tree.rootNode), )); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index afc4e137..7cff4aad 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:recase/recase.dart'; +import 'package:uuid/uuid.dart'; import 'package:path/path.dart' as p; mixin PBPlatformOrientationGeneration { @@ -22,9 +23,9 @@ mixin PBPlatformOrientationGeneration { '/$formatedName' + '/${formatedName}_platform_builder.dart', )); - if (platformsMap.length > 1) { return WriteScreenCommand( + Uuid().v4(), formatedName + '_platform_builder.dart', formatedName, _getPlatformInstance(platformsMap, screenName, cookedImports), diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 90877c6b..7a31f06f 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:uuid/uuid.dart'; enum TREE_TYPE { MISC, @@ -8,6 +9,9 @@ enum TREE_TYPE { } class PBIntermediateTree { + String _UUID; + String get UUID => _UUID; + TREE_TYPE tree_type = TREE_TYPE.SCREEN; PBGenerationViewData data; PBIntermediateNode _rootNode; @@ -32,6 +36,7 @@ class PBIntermediateTree { PBIntermediateTree(this.name) { _dependentsOn = {}; + _UUID = Uuid().v4(); } /// Adding [PBIntermediateTree] as a dependecy. diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index f16ef7eb..6e049c35 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -40,13 +40,13 @@ class PBPlatformOrientationLinkerService { // if there are more than 1 orientation on the project if (hasMultipleOrientations()) { tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(OrientationBuilderCommand()); + .add(OrientationBuilderCommand(tree.UUID)); } // Add responsive layout builder template to the project // if there are more than 1 plataform on the project if (hasMultiplePlatforms()) { tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(ResponsiveLayoutBuilderCommand()); + .add(ResponsiveLayoutBuilderCommand(tree.UUID)); _addBreakpoints(tree); } @@ -208,7 +208,7 @@ class PBPlatformOrientationLinkerService { Map bp = MainInfo().configurations['breakpoints'].cast(); bp.forEach((key, value) { - var cmd = AddConstantCommand(key, 'num', value.toString()); + var cmd = AddConstantCommand(tree.UUID, key, 'num', value.toString()); tree.rootNode.currentContext.project.genProjectData.commandQueue .add(cmd); }); diff --git a/test/lib/generation/commands/add_constant_command_test.dart b/test/lib/generation/commands/add_constant_command_test.dart index 53a4c04d..55ddc99f 100644 --- a/test/lib/generation/commands/add_constant_command_test.dart +++ b/test/lib/generation/commands/add_constant_command_test.dart @@ -19,8 +19,8 @@ void main() { setUp(() { strategy = MockFSStrategy(); - const1 = AddConstantCommand(const1V[0], const1V[1], const1V[2]); - const2 = AddConstantCommand(const2V[0], const2V[1], const2V[2]); + const1 = AddConstantCommand('UUID', const1V[0], const1V[1], const1V[2]); + const2 = AddConstantCommand('UUID', const2V[0], const2V[1], const2V[2]); when(strategy.GENERATED_PROJECT_PATH).thenReturn('temp/'); }); test('Testing Adding Constants To Project', () async { diff --git a/test/lib/generation/commands/add_dependency_command_test.dart b/test/lib/generation/commands/add_dependency_command_test.dart index d673e5db..e1afe79c 100644 --- a/test/lib/generation/commands/add_dependency_command_test.dart +++ b/test/lib/generation/commands/add_dependency_command_test.dart @@ -19,7 +19,7 @@ void main() { setUp(() { package = 'auto_size_text'; version = '^2.1.0'; - command = AddDependencyCommand(package, version); + command = AddDependencyCommand('UUID', package, version); strategy = MockFSStrategy(); }); diff --git a/test/lib/generation/commands/write_screen_command_test.dart b/test/lib/generation/commands/write_screen_command_test.dart index 230e18d7..da3f9755 100644 --- a/test/lib/generation/commands/write_screen_command_test.dart +++ b/test/lib/generation/commands/write_screen_command_test.dart @@ -40,7 +40,7 @@ void main() { FileStructureStrategy strategy; setUp(() { - command = WriteScreenCommand('test_screen.dart', '', screenData); + command = WriteScreenCommand('UUID', 'test_screen.dart', '', screenData); strategy = MockFSStrategy(); when(strategy.GENERATED_PROJECT_PATH).thenReturn('temp/'); }); diff --git a/test/lib/generation/commands/write_symbol_command_test.dart b/test/lib/generation/commands/write_symbol_command_test.dart index 25a4018d..c43d7e42 100644 --- a/test/lib/generation/commands/write_symbol_command_test.dart +++ b/test/lib/generation/commands/write_symbol_command_test.dart @@ -31,7 +31,7 @@ void main() { FileStructureStrategy strategy; setUp(() { - command = WriteSymbolCommand('test_symbol.dart', symData); + command = WriteSymbolCommand('UUID', 'test_symbol.dart', symData); strategy = MockFSStrategy(); when(strategy.GENERATED_PROJECT_PATH).thenReturn('temp/'); }); diff --git a/test/lib/generation/import_test.dart b/test/lib/generation/import_test.dart index 9f809249..0ebfd92a 100644 --- a/test/lib/generation/import_test.dart +++ b/test/lib/generation/import_test.dart @@ -1,47 +1,40 @@ +import 'dart:io'; + import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/util/topo_tree_iterator.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:test/test.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; class NodeMock extends Mock implements PBIntermediateNode {} -void main() { - // Will test IntermediateNode that needs imports - // and an IntermediateNode without imports - var iNodeWithImports, iNodeWithoutImports; +class FileStructureStrategyMock extends Mock implements FileStructureStrategy {} - /// Three intermediateNodes that will generate import - var importee1, importee2, importee3; - var genCache; +class FileMock extends Mock implements File {} - PBIntermediateTree tree0, tree1, tree2; - group('Import test', () { +void main() { + group('[PBIntermediateTree] process order test', () { + PBIntermediateTree tree0, tree1, tree2; setUp(() { - iNodeWithImports = NodeMock(); - iNodeWithoutImports = NodeMock(); - importee1 = NodeMock(); - importee2 = NodeMock(); - importee3 = NodeMock(); - genCache = PBGenCache(); - tree0 = PBIntermediateTree('Tree0'); - tree1 = PBIntermediateTree('Tree1'); - tree2 = PBIntermediateTree('Tree2'); + tree0.rootNode = NodeMock(); + when(tree0.rootNode.UUID).thenReturn('00-00-01'); + when(tree0.rootNode.name).thenReturn('Tree0'); - when(iNodeWithImports.UUID).thenReturn('00-00-00'); - when(iNodeWithoutImports.UUID).thenReturn('00-01-00'); - when(importee1.UUID).thenReturn('00-00-01'); - when(importee2.UUID).thenReturn('00-00-02'); - when(importee3.UUID).thenReturn('00-00-03'); + tree1 = PBIntermediateTree('Tree1'); + tree1.rootNode = NodeMock(); + when(tree1.rootNode.UUID).thenReturn('00-00-02'); + when(tree1.rootNode.name).thenReturn('Tree1'); - when(iNodeWithImports.child).thenReturn(importee1); - when(importee1.child).thenReturn(importee2); - when(importee2.child).thenReturn(importee3); + tree2 = PBIntermediateTree('Tree2'); + tree2.rootNode = NodeMock(); + when(tree2.rootNode.UUID).thenReturn('00-00-03'); + when(tree2.rootNode.name).thenReturn('Tree2'); }); - test('Testing how [PBIntermediateTree] are processed.', () { ///[PBIntermediateTree]s that are going to be generated. The treees inside of the list ///are dependent on each other, therefore, to ensure import availability, trees need to @@ -49,18 +42,22 @@ void main() { var pbIntermeidateTrees = []; /// `tree1` is going to depend on `tree0` and `tree0` depends on `tree2`. - /// ?t0? - /// / \ - /// t1 t2 + /// t1 --> t0 --> t2 + /// The correct order should be: `[t2, t0, t1]`, + /// because t2 has dependets, therefore, it needs to be processed first. tree1.addDependent(tree0); tree0.addDependent(tree2); + + //The initial order should't manner the end result pbIntermeidateTrees.addAll([tree0, tree2, tree1]); var dependencyIterator = IntermediateTopoIterator(pbIntermeidateTrees); - var correctOrder = [tree1, tree0, tree2].iterator; + var correctOrder = [tree2, tree0, tree1].iterator; while (dependencyIterator.moveNext() && correctOrder.moveNext()) { - expect(dependencyIterator.current == correctOrder.current, true); + expect(dependencyIterator.current == correctOrder.current, true, + reason: + 'The [PBIntermediateTree]s are not being processed in the correct order in respect to their dependencies'); } }); @@ -71,45 +68,52 @@ void main() { var pbIntermeidateTrees = []; /// a cycle between all three [PBIntermediateTree]s - /// t0 - /// / \ - /// t1----?t2 + /// + /// + /// `tree1` --> `tree0` --> `tree2` + /// <\ / + /// ---------- tree1.addDependent(tree0); tree0.addDependent(tree2); - tree2.addDependent(tree2); + tree0.addDependent(tree1); pbIntermeidateTrees.addAll([tree0, tree2, tree1]); - var dependencyIterator = - IntermediateTopoIterator(pbIntermeidateTrees); - var correctOrder = [tree1, tree0, tree2].iterator; - while (dependencyIterator.moveNext() && correctOrder.moveNext()) { - expect(dependencyIterator.current == correctOrder.current, true); - } + expect( + () => + IntermediateTopoIterator(pbIntermeidateTrees), + throwsA(isA()), + reason: + '[CyclicDependencyError] is not being thrown when there is a cycle in the graph'); }); - - test('Testing import generation when imports are generated', () { - //Add symbol in the same folder as importer - genCache.setPathToCache(importee1.UUID, '/path/to/page/importee1.dart'); - //Add symbol located a directory above importer - genCache.setPathToCache(importee2.UUID, '/path/to/importee2.dart'); - //Add symbol located a directory below importer - genCache.setPathToCache( - importee3.UUID, '/path/to/page/sub/importee3.dart'); - - // Find the imports of importer.dart - var imports = ImportHelper.findImports( - iNodeWithImports, '/path/to/page/importer.dart'); - - expect(imports.length, 3); - expect(imports.contains('./importee1.dart'), true); - expect(imports.contains('../importee2.dart'), true); - expect(imports.contains('./sub/importee3.dart'), true); + }); + group('Import paths extraction test', () { + FileStructureStrategy _fileStructureStrategy; + ImportHelper importHelper; + var completePath = + 'desktop/project/lib/screens/homescreen/some_dart_page.dart'; + var genPath = 'desktop/project/'; + setUp(() { + _fileStructureStrategy = FileStructureStrategyMock(); + importHelper = ImportHelper(); + + when(_fileStructureStrategy.writeDataToFile(any, any, any)) + .thenAnswer((invocation) { + var dir = invocation.positionalArguments[1]; + var name = invocation.positionalArguments[2]; + var uuid = invocation.namedArguments['UUID'] ?? 'UUID'; + importHelper.fileCreated( + FlutterFileStructureStrategy(genPath, null, null) + .getFile(dir, name) + .path, + uuid); + }); + when(_fileStructureStrategy.GENERATED_PROJECT_PATH).thenReturn(genPath); }); - - test('Testing import generation when no imports are generated', () { - var noImports = ImportHelper.findImports( - iNodeWithoutImports, '/path/to/page/not_importer.dart'); - expect(noImports.length, 0); + test('Testing import generation when imports are generated', () { + var command = WriteScreenCommand( + 'UUID', 'some_dart_page.dart', 'homescreen/', 'dummy code'); + command.write(_fileStructureStrategy); + expect(importHelper.getImport('UUID'), completePath); }); }); } From 20cfa0ddded63e055063a193bbbe25ee37ce13bf Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 20 May 2021 14:55:36 -0600 Subject: [PATCH 105/404] Added Eddie's changes suggestions --- lib/generation/generators/util/pb_input_formatter.dart | 6 +----- .../pb_generation_configuration.dart | 2 +- lib/interpret_and_optimize/helpers/pb_gen_cache.dart | 5 ++--- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/generation/generators/util/pb_input_formatter.dart b/lib/generation/generators/util/pb_input_formatter.dart index 75a35733..0aab286d 100644 --- a/lib/generation/generators/util/pb_input_formatter.dart +++ b/lib/generation/generators/util/pb_input_formatter.dart @@ -14,11 +14,7 @@ class PBInputFormatter { var result = _formatStr(input, spaceToUnderscore: spaceToUnderscore, destroyDigits: destroyDigits); - (isTitle) - ? result = result.camelCase - .replaceAll('_', '') - .replaceRange(0, 1, result[0].toUpperCase()) - : result = result.toLowerCase(); + (isTitle) ? result = result.pascalCase : result = result.toLowerCase(); return result; } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 6c91b848..1665da63 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -147,7 +147,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { tree.rootNode.currentContext.tree.data.platform, '$fileName', '${tree.rootNode.name.snakeCase}.dart', - await generationManager.generate(tree.rootNode), + generationManager.generate(tree.rootNode), )); } else if (tree.rootNode is InheritedScaffold) { tree.rootNode.currentContext.project.genProjectData.commandQueue diff --git a/lib/interpret_and_optimize/helpers/pb_gen_cache.dart b/lib/interpret_and_optimize/helpers/pb_gen_cache.dart index 2c161a23..153bc60a 100644 --- a/lib/interpret_and_optimize/helpers/pb_gen_cache.dart +++ b/lib/interpret_and_optimize/helpers/pb_gen_cache.dart @@ -43,10 +43,9 @@ class PBGenCache { } for (var targetPath in targetPaths) { - if (targetPath == filePath) { - continue; + if (targetPath != filePath) { + paths.add(getRelativePathFromPaths(filePath, targetPath)); } - paths.add(getRelativePathFromPaths(filePath, targetPath)); } return paths; } From 3b0b51fc060c3465e8af9213d64d24b449fbf1fc Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 20 May 2021 15:18:20 -0600 Subject: [PATCH 106/404] Added UUID field to writeDataToFile --- .../commands/export_platform_command.dart | 2 +- .../commands/orientation_builder_command.dart | 8 +++++--- .../commands/responsive_layout_builder_command.dart | 6 +++++- .../commands/write_screen_command.dart | 7 ++++++- .../commands/write_symbol_command.dart | 7 ++++++- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index a94aa4e4..7f634802 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -24,6 +24,6 @@ class ExportPlatformCommand extends NodeFileStructureCommand { 'lib/screens/$folderName/', platform.toString().toLowerCase(), ); - strategy.writeDataToFile(code, path, fileName); + strategy.writeDataToFile(code, path, fileName, UUID: UUID); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart index 3145b067..fe6196b1 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart @@ -53,8 +53,10 @@ class OrientationBuilderCommand extends FileStructureCommand { '''; strategy.writeDataToFile( - template, - p.join(strategy.GENERATED_PROJECT_PATH, DIR_TO_ORIENTATION_BUILDER), - NAME_TO_ORIENTAION_BUILDER); + template, + p.join(strategy.GENERATED_PROJECT_PATH, DIR_TO_ORIENTATION_BUILDER), + NAME_TO_ORIENTAION_BUILDER, + UUID: UUID, + ); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 0b368c0b..52b4f888 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -47,7 +47,11 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { '''; strategy.writeDataToFile( - template, DIR_TO_RESPONSIVE_LAYOUT, NAME_TO_RESPONSIVE_LAYOUT); + template, + DIR_TO_RESPONSIVE_LAYOUT, + NAME_TO_RESPONSIVE_LAYOUT, + UUID: UUID, + ); } String _generatePlatformWidgets(List platforms) { diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 9f64ad32..25ae19be 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -19,7 +19,12 @@ class WriteScreenCommand extends NodeFileStructureCommand { Future write(FileStructureStrategy strategy) { var absPath = p.join(strategy.GENERATED_PROJECT_PATH, SCREEN_PATH, relativePath); - strategy.writeDataToFile(code, absPath, name); + strategy.writeDataToFile( + code, + absPath, + name, + UUID: UUID, + ); return Future.value(p.join(absPath, name)); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 5b7914a2..828fe48b 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -15,7 +15,12 @@ class WriteSymbolCommand extends NodeFileStructureCommand { @override Future write(FileStructureStrategy strategy) { var absPath = p.join(strategy.GENERATED_PROJECT_PATH, SYMBOL_PATH); - strategy.writeDataToFile(code, absPath, name); + strategy.writeDataToFile( + code, + absPath, + name, + UUID: UUID, + ); return Future.value(p.join(absPath, name)); } } From a763d6f09d49ef8b45193983db6e46089e5ef29e Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 20 May 2021 15:41:10 -0600 Subject: [PATCH 107/404] Added null safety --- .../pb_platform_orientation_generation_mixin.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 7cff4aad..39e026e0 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -92,7 +92,9 @@ mixin PBPlatformOrientationGeneration { Set _cookImports(Set rawImports, String possiblePath) { var result = {}; rawImports.forEach((import) { - result.add(PBGenCache().getRelativePathFromPaths(possiblePath, import)); + if (possiblePath != null && import != null) { + result.add(PBGenCache().getRelativePathFromPaths(possiblePath, import)); + } }); return result; } From 9776efd0e3c7b85ce2f3524bf10b20bc6188a549 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 20 May 2021 15:41:36 -0600 Subject: [PATCH 108/404] Get imports by tree UUID --- .../pb_generation_configuration.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 1665da63..11dda70a 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -23,7 +23,6 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; -import 'package:path/path.dart' as p; abstract class GenerationConfiguration with PBPlatformOrientationGeneration { FileStructureStrategy fileStructureStrategy; @@ -223,7 +222,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { commandObservers .forEach((observer) => observer.commandCreated(newCommand)); } - _importProcessor; }); } @@ -233,8 +231,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var imports = {}; platformOrientationMap.forEach((key, map) { map.forEach((key, tree) { - imports.add(_importProcessor.getImport( - p.basenameWithoutExtension(tree.rootNode.name.snakeCase))); + imports.add(_importProcessor.getImport(tree.UUID)); }); }); // TODO: add import to responsive layout builder From e8c10a0da4b3a744352f559d1b9e8016287b6077 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 20 May 2021 15:47:52 -0600 Subject: [PATCH 109/404] Added imports to platform and orientation builder --- .../commands/orientation_builder_command.dart | 5 +++-- .../responsive_layout_builder_command.dart | 4 ++-- .../pb_generation_configuration.dart | 14 ++++++++++++++ .../pb_platform_orientation_generation_mixin.dart | 1 - 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart index fe6196b1..9fc0f951 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart @@ -3,8 +3,9 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; class OrientationBuilderCommand extends FileStructureCommand { - final DIR_TO_ORIENTATION_BUILDER = 'lib/widgets/'; - final NAME_TO_ORIENTAION_BUILDER = 'responsive_orientation_builder.dart'; + static final DIR_TO_ORIENTATION_BUILDER = 'lib/widgets/'; + static final NAME_TO_ORIENTAION_BUILDER = + 'responsive_orientation_builder.dart'; OrientationBuilderCommand(String UUID) : super(UUID); diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 9c4f7ad6..f8d11213 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -6,8 +6,8 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; class ResponsiveLayoutBuilderCommand extends FileStructureCommand { - final DIR_TO_RESPONSIVE_LAYOUT = 'lib/widgets/'; - final NAME_TO_RESPONSIVE_LAYOUT = 'responsive_layout_builder.dart'; + static final DIR_TO_RESPONSIVE_LAYOUT = 'lib/widgets/'; + static final NAME_TO_RESPONSIVE_LAYOUT = 'responsive_layout_builder.dart'; ResponsiveLayoutBuilderCommand(String UUID) : super(UUID); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 11dda70a..60e06b9f 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -4,6 +4,8 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_view_data import 'package:parabeac_core/generation/generators/util/topo_tree_iterator.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; @@ -23,6 +25,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; +import 'package:path/path.dart' as p; abstract class GenerationConfiguration with PBPlatformOrientationGeneration { FileStructureStrategy fileStructureStrategy; @@ -215,6 +218,17 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { currentMap.forEach((screenName, platformsMap) { var rawImports = getPlatformImports(screenName); + rawImports.add(p.join( + mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH + + OrientationBuilderCommand.DIR_TO_ORIENTATION_BUILDER + + OrientationBuilderCommand.NAME_TO_ORIENTAION_BUILDER, + )); + rawImports.add(p.join( + mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH + + ResponsiveLayoutBuilderCommand.DIR_TO_RESPONSIVE_LAYOUT + + ResponsiveLayoutBuilderCommand.NAME_TO_RESPONSIVE_LAYOUT, + )); + var newCommand = generatePlatformInstance( platformsMap, screenName, mainTree, rawImports); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 39e026e0..b001d0de 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -40,7 +40,6 @@ mixin PBPlatformOrientationGeneration { var className = screenName.pascalCase; return ''' import 'package:flutter/material.dart'; - import '../../widgets/responsive_layout_builder.dart'; ${_serveImports(cookedImports)} class ${className}PlatformBuilder extends StatelessWidget { From db17044f8c709a6d32e19ed4e3158022f8f04417 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 20 May 2021 16:29:11 -0600 Subject: [PATCH 110/404] Executing commands by calling observers in GenerationConfiguration --- .../pb_generation_configuration.dart | 68 +++++++++++++------ 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index cd65666f..05dc9a1d 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -18,6 +18,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; @@ -136,32 +137,44 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } await _iterateNode(tree.rootNode); + if (_importProcessor.imports.isNotEmpty) { + _traverseTreeForImports(tree); + } + // _commitImports(tree.rootNode, tree.name.snakeCase, fileName); if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { - tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(ExportPlatformCommand( - tree.UUID, - tree.rootNode.currentContext.tree.data.platform, - '$fileName', - '$fileName${getPlatformOrientationName(tree.rootNode)}.dart', - generationManager.generate(tree.rootNode), - )); + commandObservers.forEach( + (observer) => observer.commandCreated( + ExportPlatformCommand( + tree.UUID, + tree.rootNode.currentContext.tree.data.platform, + '$fileName', + '$fileName${getPlatformOrientationName(tree.rootNode)}.dart', + generationManager.generate(tree.rootNode), + ), + ), + ); } else if (tree.rootNode is InheritedScaffold) { - tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(WriteScreenCommand( - tree.UUID, - '$fileName.dart', - '${tree.name.snakeCase}', - generationManager.generate(tree.rootNode), - )); + commandObservers.forEach( + (observer) => observer.commandCreated( + WriteScreenCommand( + tree.UUID, + '$fileName.dart', + '${tree.name.snakeCase}', + generationManager.generate(tree.rootNode), + ), + ), + ); } else { - tree.rootNode.currentContext.project.genProjectData.commandQueue.add( - WriteSymbolCommand( - tree.UUID, - '$fileName.dart', - generationManager.generate(tree.rootNode), - relativePath: tree.name.snakeCase + '/', + commandObservers.forEach( + (observer) => observer.commandCreated( + WriteSymbolCommand( + tree.UUID, + '$fileName.dart', + generationManager.generate(tree.rootNode), + relativePath: tree.name.snakeCase + '/', + ), ), ); } @@ -169,6 +182,19 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await _commitDependencies(pb_project.projectName); } + void _traverseTreeForImports(PBIntermediateTree tree) { + var iter = tree.dependentOn; + + if (iter.moveNext()) { + var dependency = iter.current; + for (var key in _importProcessor.imports.keys) { + if (key == dependency.UUID) { + tree.rootNode.managerData.addImport(_importProcessor.imports[key]); + } + } + } + } + void registerMiddleware(Middleware middleware) { if (middleware != null) { middleware.generationManager = generationManager; From 84c0528f0e95638d62364995b91c4f0b3efc70aa Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 20 May 2021 16:40:57 -0600 Subject: [PATCH 111/404] Using commandObservers for PlatformCommand --- .../pb_generation_configuration.dart | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 9f4e2267..5550fd60 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -148,14 +148,15 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { getPlatformOrientationName(tree.rootNode); - tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(ExportPlatformCommand( - tree.UUID, - tree.rootNode.currentContext.tree.data.platform, - '$fileName', - '${tree.rootNode.name.snakeCase}.dart', - generationManager.generate(tree.rootNode), - )); + commandObservers.forEach( + (observer) => ExportPlatformCommand( + tree.UUID, + tree.rootNode.currentContext.tree.data.platform, + '$fileName', + '${tree.rootNode.name.snakeCase}.dart', + generationManager.generate(tree.rootNode), + ), + ); } else if (tree.rootNode is InheritedScaffold) { commandObservers.forEach( (observer) => observer.commandCreated( From e94e16e097a71df3c4bc1a5fe4b6b77d422175c2 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 20 May 2021 17:09:06 -0600 Subject: [PATCH 112/404] Add relative WIDGET_PATH to PlatformCommand --- .../commands/export_platform_command.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index dbee4620..4e317e2e 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -8,6 +8,7 @@ class ExportPlatformCommand extends NodeFileStructureCommand { PLATFORM platform; String fileName; String folderName; + final String WIDGET_PATH = 'lib/screens'; ExportPlatformCommand( String UUID, @@ -21,7 +22,7 @@ class ExportPlatformCommand extends NodeFileStructureCommand { Future write(FileStructureStrategy strategy) async { var path = p.join( strategy.GENERATED_PROJECT_PATH, - 'lib/screens/$folderName/', + '$WIDGET_PATH/$folderName/', platform.toString().toLowerCase().replaceAll('platform.', ''), ); strategy.writeDataToFile(code, path, fileName, UUID: UUID); From c6fcb00005c252f664ec7b58ecfc0a12c30986ea Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 20 May 2021 17:09:43 -0600 Subject: [PATCH 113/404] Passing tree path to import-traversal method --- .../pb_generation_configuration.dart | 78 +++++++++++-------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 5550fd60..5e39a066 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -20,6 +20,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; @@ -140,58 +141,71 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } await _iterateNode(tree.rootNode); - if (_importProcessor.imports.isNotEmpty) { - _traverseTreeForImports(tree); - } - - // _commitImports(tree.rootNode, tree.name.snakeCase, fileName); - if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { getPlatformOrientationName(tree.rootNode); - commandObservers.forEach( - (observer) => ExportPlatformCommand( - tree.UUID, - tree.rootNode.currentContext.tree.data.platform, - '$fileName', - '${tree.rootNode.name.snakeCase}.dart', - generationManager.generate(tree.rootNode), - ), + var command = ExportPlatformCommand( + tree.UUID, + tree.rootNode.currentContext.tree.data.platform, + '$fileName', + '${tree.rootNode.name.snakeCase}.dart', + generationManager.generate(tree.rootNode), ); + + if (_importProcessor.imports.isNotEmpty) { + _traverseTreeForImports(tree, + '${pbProject.projectAbsPath}${command.WIDGET_PATH}/$fileName.dart'); + } + commandObservers + .forEach((observer) => observer.commandCreated(command)); } else if (tree.rootNode is InheritedScaffold) { + var command = WriteScreenCommand( + tree.UUID, + '$fileName.dart', + '${tree.name.snakeCase}', + generationManager.generate(tree.rootNode), + ); + + if (_importProcessor.imports.isNotEmpty) { + var treePath = + '${pbProject.projectAbsPath}${WriteScreenCommand.SCREEN_PATH}/$fileName.dart'; + _traverseTreeForImports(tree, treePath); + } + commandObservers.forEach( - (observer) => observer.commandCreated( - WriteScreenCommand( - tree.UUID, - '$fileName.dart', - '${tree.name.snakeCase}', - generationManager.generate(tree.rootNode), - ), - ), + (observer) => observer.commandCreated(command), ); } else { + var command = WriteSymbolCommand( + tree.UUID, + '$fileName.dart', + generationManager.generate(tree.rootNode), + relativePath: tree.name.snakeCase + '/', + ); + + if (_importProcessor.imports.isNotEmpty) { + var treePath = + '${pbProject.projectAbsPath}${command.SYMBOL_PATH}/${command.relativePath}$fileName.dart'; + _traverseTreeForImports(tree, treePath); + } + commandObservers.forEach( - (observer) => observer.commandCreated( - WriteSymbolCommand( - tree.UUID, - '$fileName.dart', - generationManager.generate(tree.rootNode), - relativePath: tree.name.snakeCase + '/', - ), - ), + (observer) => observer.commandCreated(command), ); } } await _commitDependencies(pb_project.projectName); } - void _traverseTreeForImports(PBIntermediateTree tree) { + void _traverseTreeForImports(PBIntermediateTree tree, String treeAbsPath) { var iter = tree.dependentOn; if (iter.moveNext()) { var dependency = iter.current; for (var key in _importProcessor.imports.keys) { if (key == dependency.UUID) { - tree.rootNode.managerData.addImport(_importProcessor.imports[key]); + var relativePath = PBGenCache().getRelativePathFromPaths( + treeAbsPath, _importProcessor.imports[key]); + tree.rootNode.managerData.addImport(relativePath); } } } From 9b2919506b9db833321f5ba6871c10da40c0a15b Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Thu, 20 May 2021 18:04:17 -0600 Subject: [PATCH 114/404] Solved issue #429, the problem was that the commands that were being created were never being invoked, therefore, you resulted with no screens been writen into the filesystem. --- SketchAssetConverter | 2 +- lib/configurations/configurations.json | 28 ++++++++++--------- .../pb_generation_configuration.dart | 9 ++---- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/SketchAssetConverter b/SketchAssetConverter index 1b5f17f1..1b5effbd 160000 --- a/SketchAssetConverter +++ b/SketchAssetConverter @@ -1 +1 @@ -Subproject commit 1b5f17f1dc78d907082eada8eaa79b820908eccf +Subproject commit 1b5effbd220ff03015bc4b288184005e4443f056 diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index 681348d0..39805d2b 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -1,14 +1,16 @@ { - "default": { - "widgetStyle": "Material", - "widgetType": "Stateless", - "widgetSpacing": "Expanded", - "layoutPrecedence": ["column", "row", "stack"] - }, - "state-management": "none", - "breakpoints": { - "mobile": 360, - "tablet": 600, - "desktop": 1280 - } -} + "widgetStyle": "Material", + "widgetType": "Stateless", + "widgetSpacing": "Expanded", + "layoutPrecedence": [ + "column", + "row", + "stack" + ], + "state-management": "provider", + "breakpoints": { + "mobile": 360, + "tablet": 600, + "desktop": 1280 + } +} \ No newline at end of file diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 518b1624..575297bc 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -139,23 +139,20 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { // _commitImports(tree.rootNode, tree.name.snakeCase, fileName); if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { - tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(ExportPlatformCommand( + fileStructureStrategy.commandCreated(ExportPlatformCommand( tree.rootNode.currentContext.tree.data.platform, '$fileName', '$fileName${getPlatformOrientationName(tree.rootNode)}.dart', generationManager.generate(tree.rootNode), )); } else if (tree.rootNode is InheritedScaffold) { - tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(WriteScreenCommand( + fileStructureStrategy.commandCreated(WriteScreenCommand( '$fileName.dart', '${tree.name}', generationManager.generate(tree.rootNode), )); } else { - tree.rootNode.currentContext.project.genProjectData.commandQueue - .add(WriteSymbolCommand( + fileStructureStrategy.commandCreated(WriteSymbolCommand( '$fileName.dart', generationManager.generate(tree.rootNode), )); From 5f0d73e8eca8f3ecb79a5b7cfcb3f7ca59895ae4 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Thu, 20 May 2021 18:31:43 -0600 Subject: [PATCH 115/404] Fixed a small bug that wrote the main.dart wrong --- .../pb_file_structure_strategy.dart | 11 +++++++---- .../pb_generation_configuration.dart | 7 ++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 809d6c01..e396dc27 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -119,8 +119,7 @@ abstract class FileStructureStrategy implements CommandInvoker { return Future.value(); } - String getViewPath(String fileName) => - '$_viewDirectoryPath$fileName.dart'; + String getViewPath(String fileName) => '$_viewDirectoryPath$fileName.dart'; @override void commandCreated(FileStructureCommand command) { @@ -137,8 +136,12 @@ abstract class FileStructureStrategy implements CommandInvoker { /// be used. /// /// [FileWriterObserver]s are going to be notfied of the new created file. - void writeDataToFile(String data, String directory, String name, - {String UUID}) { + void writeDataToFile( + String data, + String directory, + String name, { + String UUID, + }) { var file = _getFile(directory, name); file.createSync(recursive: true); file.writeAsStringSync(data); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 575297bc..b24c71a1 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -23,6 +23,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; +import 'package:path/path.dart' as p; abstract class GenerationConfiguration with PBPlatformOrientationGeneration { FileStructureStrategy fileStructureStrategy; @@ -132,7 +133,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } if (tree.rootNode is InheritedScaffold && (tree.rootNode as InheritedScaffold).isHomeScreen) { - _setMainScreen(tree.rootNode, '$relPath.dart'); + await _setMainScreen(tree.rootNode, '$relPath.dart'); } await _iterateNode(tree.rootNode); @@ -191,12 +192,12 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } } - void _setMainScreen(InheritedScaffold node, String outputMain) async { + Future _setMainScreen(InheritedScaffold node, String outputMain) async { var writer = pageWriter; if (writer is PBFlutterWriter) { await writer.writeMainScreenWithHome( node.name, - fileStructureStrategy.GENERATED_PROJECT_PATH + 'lib/main.dart', + p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'lib/main.dart'), 'screens/$outputMain'); } } From 0e2318216691bf93a13d1c59d6c73e5edb778aed Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 20 May 2021 15:47:52 -0600 Subject: [PATCH 116/404] Just modifying a path that was missed --- .../commands/orientation_builder_command.dart | 5 +++-- .../responsive_layout_builder_command.dart | 4 ++-- .../pb_generation_configuration.dart | 14 ++++++++++++++ .../pb_platform_orientation_generation_mixin.dart | 13 ++++++------- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart index fe6196b1..9fc0f951 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart @@ -3,8 +3,9 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; class OrientationBuilderCommand extends FileStructureCommand { - final DIR_TO_ORIENTATION_BUILDER = 'lib/widgets/'; - final NAME_TO_ORIENTAION_BUILDER = 'responsive_orientation_builder.dart'; + static final DIR_TO_ORIENTATION_BUILDER = 'lib/widgets/'; + static final NAME_TO_ORIENTAION_BUILDER = + 'responsive_orientation_builder.dart'; OrientationBuilderCommand(String UUID) : super(UUID); diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 9c4f7ad6..f8d11213 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -6,8 +6,8 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; class ResponsiveLayoutBuilderCommand extends FileStructureCommand { - final DIR_TO_RESPONSIVE_LAYOUT = 'lib/widgets/'; - final NAME_TO_RESPONSIVE_LAYOUT = 'responsive_layout_builder.dart'; + static final DIR_TO_RESPONSIVE_LAYOUT = 'lib/widgets/'; + static final NAME_TO_RESPONSIVE_LAYOUT = 'responsive_layout_builder.dart'; ResponsiveLayoutBuilderCommand(String UUID) : super(UUID); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 11dda70a..60e06b9f 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -4,6 +4,8 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_view_data import 'package:parabeac_core/generation/generators/util/topo_tree_iterator.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; @@ -23,6 +25,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; +import 'package:path/path.dart' as p; abstract class GenerationConfiguration with PBPlatformOrientationGeneration { FileStructureStrategy fileStructureStrategy; @@ -215,6 +218,17 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { currentMap.forEach((screenName, platformsMap) { var rawImports = getPlatformImports(screenName); + rawImports.add(p.join( + mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH + + OrientationBuilderCommand.DIR_TO_ORIENTATION_BUILDER + + OrientationBuilderCommand.NAME_TO_ORIENTAION_BUILDER, + )); + rawImports.add(p.join( + mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH + + ResponsiveLayoutBuilderCommand.DIR_TO_RESPONSIVE_LAYOUT + + ResponsiveLayoutBuilderCommand.NAME_TO_RESPONSIVE_LAYOUT, + )); + var newCommand = generatePlatformInstance( platformsMap, screenName, mainTree, rawImports); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 39e026e0..183f1e21 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -18,10 +18,10 @@ mixin PBPlatformOrientationGeneration { var cookedImports = _cookImports( rawImports, p.join( - mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH + - WriteScreenCommand.SCREEN_PATH + - '/$formatedName' + - '/${formatedName}_platform_builder.dart', + mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH, + WriteScreenCommand.SCREEN_PATH, + '/$formatedName', + '/${formatedName}_platform_builder.dart', )); if (platformsMap.length > 1) { return WriteScreenCommand( @@ -40,7 +40,6 @@ mixin PBPlatformOrientationGeneration { var className = screenName.pascalCase; return ''' import 'package:flutter/material.dart'; - import '../../widgets/responsive_layout_builder.dart'; ${_serveImports(cookedImports)} class ${className}PlatformBuilder extends StatelessWidget { @@ -67,7 +66,7 @@ mixin PBPlatformOrientationGeneration { ), '''; } else { - result += '${platform}Widget: ${nameWithPlatform}(),'; + result += '${platform}Widget: $nameWithPlatform(),'; } }); return result; @@ -102,7 +101,7 @@ mixin PBPlatformOrientationGeneration { String _serveImports(Set cookedImports) { var result = ''; cookedImports.forEach((import) { - result += 'import \'${import}\';\n'; + result += 'import \'$import\';\n'; }); return result; } From 454aa2aad3b94d38bbfc0d34d419f6cc90fe7224 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 20 May 2021 19:37:13 -0600 Subject: [PATCH 117/404] Using `path` package for creating the tree's path. --- .../pb_generation_configuration.dart | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 5e39a066..0aa2a332 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -152,8 +152,9 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ); if (_importProcessor.imports.isNotEmpty) { - _traverseTreeForImports(tree, - '${pbProject.projectAbsPath}${command.WIDGET_PATH}/$fileName.dart'); + var treePath = p.join( + pbProject.projectAbsPath, command.WIDGET_PATH, '$fileName.dart'); + _traverseTreeForImports(tree, treePath); } commandObservers .forEach((observer) => observer.commandCreated(command)); @@ -166,8 +167,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ); if (_importProcessor.imports.isNotEmpty) { - var treePath = - '${pbProject.projectAbsPath}${WriteScreenCommand.SCREEN_PATH}/$fileName.dart'; + var treePath = p.join(pbProject.projectAbsPath, + WriteScreenCommand.SCREEN_PATH, '$fileName.dart'); _traverseTreeForImports(tree, treePath); } @@ -183,8 +184,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ); if (_importProcessor.imports.isNotEmpty) { - var treePath = - '${pbProject.projectAbsPath}${command.SYMBOL_PATH}/${command.relativePath}$fileName.dart'; + var treePath = p.join(pbProject.projectAbsPath, command.SYMBOL_PATH, + command.relativePath, '$fileName.dart'); _traverseTreeForImports(tree, treePath); } @@ -196,6 +197,10 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await _commitDependencies(pb_project.projectName); } + /// Method that traverses `tree`'s dependencies and looks for an import path from + /// [ImportHelper]. + /// + /// If an import path is found, it will be added to the `tree`'s data. void _traverseTreeForImports(PBIntermediateTree tree, String treeAbsPath) { var iter = tree.dependentOn; @@ -209,6 +214,23 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } } } + + var stack = [tree.rootNode]; + while (stack.isNotEmpty) { + var currentNode = stack.removeLast(); + + for (var key in _importProcessor.imports.keys) { + if (key == currentNode.UUID) { + var relativePath = PBGenCache().getRelativePathFromPaths( + treeAbsPath, _importProcessor.imports[key]); + tree.rootNode.managerData.addImport(relativePath); + } + } + + for (var attr in currentNode.attributes) { + stack.add(attr.attributeNode); + } + } } void registerMiddleware(Middleware middleware) { From fe5923f66c490560e7525fb17edb52bb4928fd96 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Fri, 21 May 2021 16:55:16 -0600 Subject: [PATCH 118/404] Modify appendDatatoFile() method to not write "[]" --- .../pb_file_structure_strategy.dart | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index a09ba11f..b05f4bd4 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -161,10 +161,15 @@ abstract class FileStructureStrategy implements CommandInvoker { var modLines = modFile(fileLines); if (fileLines != modLines) { - file.writeAsStringSync(modFile(fileLines).toString()); + var buffer = StringBuffer(); + modLines.forEach(buffer.writeln); + file.writeAsStringSync(buffer.toString()); } } else if (createFileIfNotFound) { - writeDataToFile(modFile([]).toString(), directory, name, UUID: UUID); + var modLines = modFile([]); + var buffer = StringBuffer(); + modLines.forEach(buffer.writeln); + writeDataToFile(buffer.toString(), directory, name, UUID: UUID); } } From c14fcd9001267c04b827e41a0bd571a6abb59169 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Fri, 21 May 2021 17:03:04 -0600 Subject: [PATCH 119/404] Remove unnecessary tree traversal from import traversal method --- .../pb_generation_configuration.dart | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index e0516f5d..abcdc19e 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -214,23 +214,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } } } - - var stack = [tree.rootNode]; - while (stack.isNotEmpty) { - var currentNode = stack.removeLast(); - - for (var key in _importProcessor.imports.keys) { - if (key == currentNode.UUID) { - var relativePath = PBGenCache().getRelativePathFromPaths( - treeAbsPath, _importProcessor.imports[key]); - tree.rootNode.managerData.addImport(relativePath); - } - } - - for (var attr in currentNode.attributes) { - stack.add(attr.attributeNode); - } - } } void registerMiddleware(Middleware middleware) { From 5c173288a469f5822a823d485d78d0b64f1bd661 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Fri, 21 May 2021 17:08:52 -0600 Subject: [PATCH 120/404] PlatformOrientation mixin generates relative paths correctly. --- .../pb_platform_orientation_generation_mixin.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 183f1e21..893e6bbb 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -20,8 +20,8 @@ mixin PBPlatformOrientationGeneration { p.join( mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH, WriteScreenCommand.SCREEN_PATH, - '/$formatedName', - '/${formatedName}_platform_builder.dart', + formatedName, + '${formatedName}_platform_builder.dart', )); if (platformsMap.length > 1) { return WriteScreenCommand( From 4c300ebf14186b499687dc40a680db3a89e5ddb4 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 21 May 2021 17:44:30 -0600 Subject: [PATCH 121/404] Fix issue with home page and duplicated pages --- .../pb_generation_configuration.dart | 34 ++++++++++++++----- ...platform_orientation_generation_mixin.dart | 10 ++++-- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index e0516f5d..3569985e 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -125,23 +125,23 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { tree.data.addImport('package:flutter/material.dart'); generationManager.data = tree.data; - var fileName = tree.rootNode?.name?.snakeCase ?? 'no_name_found'; + var fileName = tree.identifier?.snakeCase ?? 'no_name_found'; // Relative path to the file to create var relPath = '${tree.name.snakeCase}/$fileName'; // Change relative path if current tree is part of multi-platform setup - if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { + if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { var platformFolder = poLinker.stripPlatform(tree.rootNode.managerData.platform); relPath = '$fileName/$platformFolder/$fileName'; } if (tree.rootNode is InheritedScaffold && (tree.rootNode as InheritedScaffold).isHomeScreen) { - await _setMainScreen(tree.rootNode, '$relPath.dart'); + await _setMainScreen(tree, '$relPath.dart'); } await _iterateNode(tree.rootNode); - if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { + if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { getPlatformOrientationName(tree.rootNode); var command = ExportPlatformCommand( tree.UUID, @@ -199,7 +199,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { /// Method that traverses `tree`'s dependencies and looks for an import path from /// [ImportHelper]. - /// + /// /// If an import path is found, it will be added to the `tree`'s data. void _traverseTreeForImports(PBIntermediateTree tree, String treeAbsPath) { var iter = tree.dependentOn; @@ -263,14 +263,32 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } } - Future _setMainScreen(InheritedScaffold node, String outputMain) async { + Future _setMainScreen( + PBIntermediateTree tree, String outputMain) async { var writer = pageWriter; + var nodeInfo = _determineNode(tree, outputMain); if (writer is PBFlutterWriter) { await writer.writeMainScreenWithHome( - node.name, + nodeInfo[0], p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'lib/main.dart'), - 'screens/$outputMain'); + 'screens/${nodeInfo[1]}'); + } + } + + List _determineNode(PBIntermediateTree tree, String outputMain) { + var rootName = tree.rootNode.name; + if (rootName.contains('_')) { + rootName = rootName.split('_')[0].pascalCase; + } + var currentMap = PBPlatformOrientationLinkerService() + .getPlatformOrientationData(rootName); + var className = [rootName.pascalCase, '']; + if (currentMap.length > 1) { + className[0] += 'PlatformBuilder'; + className[1] = + rootName.snakeCase + '/${rootName.snakeCase}_platform_builder.dart'; } + return className; } Future generatePlatformAndOrientationInstance(PBProject mainTree) { diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 183f1e21..43f23ad6 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -74,17 +74,21 @@ mixin PBPlatformOrientationGeneration { void getPlatformOrientationName(PBIntermediateNode node) { var map = PBPlatformOrientationLinkerService() - .getPlatformOrientationData(node.name); + .getPlatformOrientationData(node.currentContext.tree.identifier); if (map.length > 1) { var platform = PBPlatformOrientationLinkerService() .stripPlatform(node.currentContext.tree.data.platform); - node.name += '_$platform'; + if (!node.name.contains('_$platform')) { + node.name += '_$platform'; + } } if (map[node.currentContext.tree.data.platform].length > 1) { var orientation = PBPlatformOrientationLinkerService() .stripOrientation(node.currentContext.tree.data.orientation); - node.name += '_$orientation'; + if (!node.name.contains('_$orientation')) { + node.name += '_$orientation'; + } } } From dbc4f16f63a1d19de6ac584c87a5b544e3beac08 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Sun, 23 May 2021 14:43:08 -0600 Subject: [PATCH 122/404] Corrected how commands are being invoked in the FileStructureStrategy. --- .../pb_generation_configuration.dart | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index a3b59375..777d7757 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -140,10 +140,11 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await _setMainScreen(tree, '$relPath.dart'); } await _iterateNode(tree.rootNode); + var command; if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { getPlatformOrientationName(tree.rootNode); - var command = ExportPlatformCommand( + command = ExportPlatformCommand( tree.UUID, tree.rootNode.currentContext.tree.data.platform, '$fileName', @@ -156,10 +157,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { pbProject.projectAbsPath, command.WIDGET_PATH, '$fileName.dart'); _traverseTreeForImports(tree, treePath); } - commandObservers - .forEach((observer) => observer.commandCreated(command)); } else if (tree.rootNode is InheritedScaffold) { - var command = WriteScreenCommand( + command = WriteScreenCommand( tree.UUID, '$fileName.dart', '${tree.name.snakeCase}', @@ -171,12 +170,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { WriteScreenCommand.SCREEN_PATH, '$fileName.dart'); _traverseTreeForImports(tree, treePath); } - - commandObservers.forEach( - (observer) => observer.commandCreated(command), - ); } else { - var command = WriteSymbolCommand( + command = WriteSymbolCommand( tree.UUID, '$fileName.dart', generationManager.generate(tree.rootNode), @@ -188,11 +183,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { command.relativePath, '$fileName.dart'); _traverseTreeForImports(tree, treePath); } - - commandObservers.forEach( - (observer) => observer.commandCreated(command), - ); } + fileStructureStrategy.commandCreated(command); } await _commitDependencies(pb_project.projectName); } From b7cd6ad14fe7440fb17667c6daeb8ceea1a0fa1b Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sun, 23 May 2021 16:20:12 -0700 Subject: [PATCH 123/404] Overrides are working on non-statemanagement generation Still a couple of bugs in provider that aren't picking up on overrides and adding some final var that isn't needed --- .../symbols/pb_instancesym_gen.dart | 185 +++++++++--------- .../util/pb_generation_view_data.dart | 2 + .../bloc_state_template_strategy.dart | 2 + .../stateful_template_strategy.dart | 2 + .../stateless_template_strategy.dart | 2 + 5 files changed, 97 insertions(+), 96 deletions(-) diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 702421b1..42d8e9d5 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -13,6 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; +import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; import 'package:quick_log/quick_log.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:recase/recase.dart'; @@ -26,73 +27,21 @@ class PBSymbolInstanceGenerator extends PBGenerator { String generate( PBIntermediateNode source, GeneratorContext generatorContext) { if (source is PBSharedInstanceIntermediateNode) { - var method_signature = source.functionCallName?.pascalCase; - if (method_signature == null) { - log.error(' Could not find master name on: $source'); - return 'Container(/** This Symbol was not found **/)'; - } - - var overrideProp = SN_UUIDtoVarName[source.UUID + '_symbolID']; - - method_signature = PBInputFormatter.formatLabel(method_signature, - destroyDigits: false, spaceToUnderscore: false, isTitle: true); var buffer = StringBuffer(); - buffer.write('LayoutBuilder( \n'); buffer.write(' builder: (context, constraints) {\n'); buffer.write(' return '); - if (overrideProp != null) { - buffer.write('${overrideProp} ?? '); - } + // If storage found an instance, get its master + var masterSymbol = + PBSymbolStorage().getSharedMasterNodeBySymbolID(source.SYMBOL_ID); - buffer.write(method_signature); - buffer.write('('); - buffer.write('constraints,'); - - // need to iterate through master symbol parametersDefsMap to pass parent variables down to children - var masterSymbol = getMasterSymbol(source.UUID); - masterSymbol.parametersDefsMap.forEach((overrideName, smParameter) { - var ovrValue = ''; - if (source.overrideValuesMap.containsKey(overrideName)) { - var param = source.overrideValuesMap[overrideName]; - switch (param.type) { - case PBSharedInstanceIntermediateNode: - ovrValue = genSymbolInstance( - param.UUID, - param.value, - source.overrideValues, - source.managerData - ); - break; - case InheritedBitmap: - ovrValue = '\"assets/${param.value["_ref"]}\",'; - break; - case TextStyle: - // hack to include import - source.currentContext.treeRoot.data.addImport( - 'package:${MainInfo().projectName}/document/shared_props.g.dart'); - ovrValue = '${SharedStyle_UUIDToName[param.value]}.textStyle,'; - break; - case Style: - // hack to include import - source.currentContext.treeRoot.data.addImport( - 'package:${MainInfo().projectName}/document/shared_props.g.dart'); - ovrValue = '${SharedStyle_UUIDToName[param.value]},'; - break; - case String: - ovrValue = '\"${param.value}\",'; - break; - default: - log.info('Unknown type ${param.type.toString()} in parameter values for symbol instance.\n'); - } - var friendlyName = SN_UUIDtoVarName[PBInputFormatter.findLastOf(smParameter.propertyName, '/')]; - buffer.write('$friendlyName: $ovrValue'); - } - }); + // recursively generate Symbol Instance constructors with overrides + buffer.write(genSymbolInstance(source.UUID, source.overrideValuesMap, + masterSymbol.parametersDefsMap, source.managerData)); - // end of return function(); - buffer.write(');\n'); + // end of return (); + buffer.write(';\n'); // end of builder: (context, constraints) { buffer.write('}\n'); // end of LayoutBuilder() @@ -103,7 +52,6 @@ class PBSymbolInstanceGenerator extends PBGenerator { } PBSharedMasterNode getMasterSymbol(String UUID) { - var masterSymbol; var nodeFound = PBSymbolStorage().getAllSymbolById(UUID); if (nodeFound is PBSharedMasterNode) { @@ -118,69 +66,114 @@ class PBSymbolInstanceGenerator extends PBGenerator { } return masterSymbol; - } - String genSymbolInstance(String overrideUUID, String UUID, - List overrideValues, + String genSymbolInstance( + String UUID, + Map mapOverrideValues, + Map mapParameterValues, PBGenerationViewData managerData, - {int depth = 1}) { - + { bool topLevel = true, + String UUIDPath = ''}) { if ((UUID == null) || (UUID == '')) { return ''; } + var buffer = StringBuffer(); var masterSymbol = getMasterSymbol(UUID); // file could have override names that don't exist? That's really odd, but we have a file that does that. if (masterSymbol == null) { - return ''; + log.error(' Could not find master symbol for UUID:: $UUID'); + return 'Container(/** This Symbol was not found **/)});'; } + var symName = masterSymbol.name; + if (symName == null) { + log.error(' Could not find master name on: $masterSymbol'); + return 'Container(/** This Symbol was not found **/)});'; + } - var fileName = masterSymbol.name.snakeCase; - managerData.addImport( - 'package:${MainInfo().projectName}/view/symbols/${fileName}.dart'); + symName = PBInputFormatter.formatLabel(symName, + destroyDigits: false, spaceToUnderscore: false, isTitle: true); - var buffer = StringBuffer(); - buffer.write('${masterSymbol.friendlyName}(constraints, '); - for (var ovrValue in overrideValues) { - var ovrUUIDStrings = ovrValue.UUID.split('/'); - if ((ovrUUIDStrings.length == depth + 1) && - (ovrUUIDStrings[depth - 1] == overrideUUID)) { - var ovrUUID = ovrUUIDStrings[depth]; - switch (ovrValue.type) { + // don't include ourselves only child symbols + if (!topLevel) { + managerData.addImport( + 'package:${MainInfo().projectName}/view/symbols/${symName.snakeCase}.dart'); + } + + // if this symbol is overridable, then put variable name + null check + var overrideProp = SN_UUIDtoVarName[UUID + '_symbolID']; + if (overrideProp != null) { + buffer.write('$overrideProp ?? '); + } + + buffer.write(symName.pascalCase); + buffer.write('(\n'); + buffer.write('constraints,\n'); + + // need to iterate through master symbol parametersDefsMap to pass parent variables down to children + + masterSymbol.parametersDefsMap.forEach((overrideName, smParameter) { + var ovrValue = ''; + overrideName = UUIDPath + overrideName; + if (mapOverrideValues.containsKey(overrideName)) { + var param = mapOverrideValues[overrideName]; + switch (param.type) { case PBSharedInstanceIntermediateNode: - buffer.write(genSymbolInstance( - ovrValue.value, ovrUUID, overrideValues, - managerData, - depth: depth + 1)); + ovrValue = genSymbolInstance( + param.value, + mapOverrideValues, + mapParameterValues, + managerData, + topLevel: false, + UUIDPath: '$UUIDPath${param.UUID}/', + ); break; case InheritedBitmap: - var name = SN_UUIDtoVarName[ovrUUID + '_image']; - buffer.write('$name: \"assets/${ovrValue.value["_ref"]}\",'); + ovrValue = '\"assets/${param.value["_ref"]}\"'; break; case TextStyle: - var name = SN_UUIDtoVarName[ovrUUID + '_textStyle']; - buffer.write( - '$name: ${SharedStyle_UUIDToName[ovrValue.value]}.textStyle,'); + // hack to include import + managerData.addImport( + 'package:${MainInfo().projectName}/document/shared_props.g.dart'); + ovrValue = '${SharedStyle_UUIDToName[param.value]}.textStyle'; break; case Style: - //var name = SN_UUIDtoVarName[ovrUUID + '_layerStyle']; - //buffer.write( - // 'layerStyle: ${SharedStyle_UUIDToName[ovrValue.value]},'); + // hack to include import + managerData.addImport( + 'package:${MainInfo().projectName}/document/shared_props.g.dart'); + ovrValue = '${SharedStyle_UUIDToName[param.value]}'; break; case String: - var name = SN_UUIDtoVarName[ovrUUID + '_stringValue'] ; - buffer.write('$name: \"${ovrValue.value}\",'); + ovrValue = '\"${param.value}\"'; break; default: - log.info('Unknown type ${ovrValue.type.toString()} in override values for symbol instance.\n'); - + log.info( + 'Unknown type ${param.type.toString()} in parameter values for symbol instance.\n'); } } - } - buffer.write('),'); + // get parameter name to pass to widget constructor + var friendlyName = SN_UUIDtoVarName[ + PBInputFormatter.findLastOf(smParameter.propertyName, '/')]; + var paramName = ''; + // check if parent widget has parameter to pass down to children + if (managerData.hasParams && + mapParameterValues.containsKey(smParameter.propertyName)) { + // yes, so pass down with optional null check + paramName = friendlyName; + if (ovrValue != '') { + paramName += ' ?? '; + } + } + if ((ovrValue != '') || (paramName != '')) { + buffer.write('$friendlyName: $paramName$ovrValue,\n'); + } + }); + + buffer.write(')\n'); + return buffer.toString(); } } diff --git a/lib/generation/generators/util/pb_generation_view_data.dart b/lib/generation/generators/util/pb_generation_view_data.dart index 509213fe..fa9eb6d3 100644 --- a/lib/generation/generators/util/pb_generation_view_data.dart +++ b/lib/generation/generators/util/pb_generation_view_data.dart @@ -8,6 +8,8 @@ class PBGenerationViewData { final Set _imports = {}; final Set _toDispose = {}; bool _isDataLocked = false; + bool hasParams = false; + PBGenerationViewData(); diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index ebda2aa1..f9bb8b3e 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -15,7 +15,9 @@ class BLoCStateTemplateStrategy extends TemplateStrategy { GeneratorContext generatorContext, {args}) { var widgetName = retrieveNodeName(node); + node.managerData.hasParams = true; var returnStatement = node.generator.generate(node, generatorContext); + node.managerData.hasParams = false; var overrides = ''; var overrideVars = ''; if (node is PBSharedMasterNode && node.overridableProperties.isNotEmpty) { diff --git a/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart index 626e482f..cbb98bf9 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; ///Generating a [StatefulWidget] @@ -12,6 +13,7 @@ class StatefulTemplateStrategy extends TemplateStrategy { var widgetName = retrieveNodeName(node); var constructorName = '$widgetName'; var returnStatement = node.generator.generate(node, generatorContext); + return ''' ${manager.generateImports()} diff --git a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart index 405537e1..d360e6c0 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart @@ -12,7 +12,9 @@ class StatelessTemplateStrategy extends TemplateStrategy { GeneratorContext generatorContext, {args}) { var widgetName = node.name; + node.managerData.hasParams = true; var returnStatement = node.generator.generate(node, generatorContext); + node.managerData.hasParams = false; var overrides = ''; var overrideVars = ''; From 4511265d5f06028a4406a420df94f1fd1b61f1d3 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sun, 23 May 2021 16:47:51 -0700 Subject: [PATCH 124/404] Fixes provider generation code and now works with overrides --- .../middleware/state_management/provider_middleware.dart | 6 +++--- .../middleware/state_management/utils/middleware_utils.dart | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 6151a5bf..e27a0d5d 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -39,7 +39,7 @@ class ProviderMiddleware extends Middleware { is StatelessTemplateStrategy) { watcher = PBVariable(watcherName, 'final ', true, '${getName(node.functionCallName).pascalCase}().${widgetName}'); - managerData.addGlobalVariable(watcher); + //managerData.addGlobalVariable(watcher); } addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); @@ -55,7 +55,7 @@ class ProviderMiddleware extends Middleware { ${modelName}(), child: LayoutBuilder( builder: (context, constraints) { - var widget = ${defaultWidget}(constraints); + var widget = ${MiddlewareUtils.generateVariableBody(node)}; context .read<${modelName}>() @@ -64,7 +64,7 @@ class ProviderMiddleware extends Middleware { return GestureDetector( onTap: () => context.read< - ${modelName}>(), // TODO: add your method to change the state here + ${modelName}>().OnGesture(), child: context .watch<${modelName}>() .currentWidget, diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index e6f80a89..e4b0c785 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -80,6 +80,10 @@ class MiddlewareUtils { Widget currentWidget; ${defaultStateName}(){} + // default provider event handler for gestures. + void OnGesture() { + } + void setCurrentWidget(Widget currentWidget) { this.currentWidget = currentWidget; } From 657473f0590d14e7009adacc3816c2613fcdedfe Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 24 May 2021 10:36:29 -0600 Subject: [PATCH 125/404] Replace `context.watch()` with `Consumer` widget --- .../middleware/state_management/provider_middleware.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 1a2901ed..a7d129e3 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -54,9 +54,9 @@ class ProviderMiddleware extends Middleware { return GestureDetector( onTap: () => context.read< ${modelName}>(), // TODO: add your method to change the state here - child: context - .watch<${modelName}>() - .currentWidget, + child: Consumer<$modelName>( + builder: (context, ${modelName.toLowerCase()}, child) => ${modelName.toLowerCase()}.currentWidget + ), ); }, ), From 6bd763c9f52c99442678e67c16e34df21d635c3c Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 24 May 2021 10:37:47 -0600 Subject: [PATCH 126/404] Remove generation of `providers` folder --- .../provider_file_structure_strategy.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart index b65cd8ba..3752095a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart @@ -5,15 +5,12 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; class ProviderFileStructureStrategy extends FileStructureStrategy { - final RELATIVE_PROVIDER_PATH = 'lib/providers/'; final RELATIVE_MODEL_PATH = 'lib/models/'; - var _providersPath; var _modelsPath; ProviderFileStructureStrategy( String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) : super(genProjectPath, pageWriter, pbProject) { - _providersPath = '${genProjectPath}${RELATIVE_PROVIDER_PATH}'; _modelsPath = '${genProjectPath}${RELATIVE_MODEL_PATH}'; } @@ -27,7 +24,6 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { } Future _generateMissingDirectories() async { - Directory(_providersPath).createSync(recursive: true); Directory(_modelsPath).createSync(recursive: true); } From c3650d5021af297c5b222121fce5ee653689b8b8 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 24 May 2021 17:16:05 -0600 Subject: [PATCH 127/404] addConstant method no longer alters reference This fixes a bug in which the list being passed to it was being edited directly through reference, causing issues. --- .../commands/add_constant_command.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index ad534966..b8ac82c9 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -26,9 +26,10 @@ class AddConstantCommand extends FileStructureCommand { List _addConstant(List lines) { var constStr = 'const $type $name = $value;'; - if (!lines.contains(constStr)) { - lines.add(constStr); + var result = List.from(lines); + if (!result.contains(constStr)) { + result.add(constStr); } - return lines; + return result; } } From 9b7c98737c9f2d0890ecf9e1db3ceb56df8abb96 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 24 May 2021 17:27:44 -0600 Subject: [PATCH 128/404] Only calling orientation and layout commands once. --- .../commands/responsive_layout_builder_command.dart | 2 -- .../services/pb_platform_orientation_linker_service.dart | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 82e6dd19..cd6ff265 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -20,7 +20,6 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { var widgetVars = _generatePlatformWidgets(platforms); var widgetInit = _generatePlatformInitializers(platforms); var breakpointChecks = _generateBreakpointStatements(platforms); - //TODO: use imports system to import material. See updated orientation builder command var template = ''' import 'package:flutter/material.dart'; import '../constants/constants.dart'; @@ -74,7 +73,6 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { // Get breakpoints from configurations and sort by value var breakpoints = MainInfo().configurations['breakpoints']; if (breakpoints == null) { - // TODO: Handle breakpoints being null breakpoints = {}; breakpoints['mobile'] = 300; breakpoints['tablet'] = 600; diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index e172dc89..8e3ee374 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -38,13 +38,13 @@ class PBPlatformOrientationLinkerService { // Add orientation builder template to the project // if there are more than 1 orientation on the project - if (hasMultipleOrientations()) { + if (platforms.length == 2) { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(OrientationBuilderCommand(tree.UUID)); } // Add responsive layout builder template to the project - // if there are more than 1 plataform on the project - if (hasMultiplePlatforms()) { + // if there are more than 1 platform on the project + if (platforms.length == 2) { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(ResponsiveLayoutBuilderCommand(tree.UUID)); _addBreakpoints(tree); From aeb89dbd5dae476cdc6e0e4ad483a7dca0d9b60e Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 24 May 2021 18:48:28 -0600 Subject: [PATCH 129/404] Changed platforms to SplayTreeSet This was done to increase efficiency and fix a bug in which the breakpoints were being generated out of order. --- .../commands/responsive_layout_builder_command.dart | 4 +--- .../pb_platform_orientation_linker_service.dart | 10 ++++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index cd6ff265..2e140093 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -78,13 +78,11 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { breakpoints['tablet'] = 600; breakpoints['desktop'] = 1280; } - var sortedMap = SplayTreeMap.from( - breakpoints, (a, b) => breakpoints[a].compareTo(breakpoints[b])); var result = ''; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; - if (sortedMap.containsKey(platform)) { + if (breakpoints.containsKey(platform)) { if (i == platforms.length - 1) { result += 'if(${platform}Widget != null){return ${platform}Widget;}'; } else { diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 8e3ee374..2de4a611 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -1,3 +1,5 @@ +import 'dart:collection'; + import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; @@ -19,7 +21,8 @@ class PBPlatformOrientationLinkerService { final Map _mapCounter = {}; /// Set of all platforms in the project - final Set _platforms = {}; + final SplayTreeSet _platforms = + SplayTreeSet((a, b) => a.index.compareTo(b.index)); /// Set of all orientations in the project final Set _orientations = {}; @@ -217,10 +220,13 @@ class PBPlatformOrientationLinkerService { } } +/// Enum of supported platforms. +/// +/// The order of this enum is important, and goes from smallest value to greatest. enum PLATFORM { - DESKTOP, MOBILE, TABLET, + DESKTOP, } enum ORIENTATION { From 6d5a80b1b57ed74a67f56887bc67a139783036bd Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 24 May 2021 19:15:38 -0600 Subject: [PATCH 130/404] Fix checking platforms instead of orientations. --- .../services/pb_platform_orientation_linker_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 2de4a611..451ea47a 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -41,7 +41,7 @@ class PBPlatformOrientationLinkerService { // Add orientation builder template to the project // if there are more than 1 orientation on the project - if (platforms.length == 2) { + if (orientations.length == 2) { tree.rootNode.currentContext.project.genProjectData.commandQueue .add(OrientationBuilderCommand(tree.UUID)); } From 51cff17d49e6d921b270f8af8b425c9bf98f375c Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Mon, 24 May 2021 21:07:09 -0700 Subject: [PATCH 131/404] Fixes imports and too many files being generated when I removed the continue; --- .../flutter_project_builder/import_helper.dart | 10 ++++++++++ lib/generation/generators/middleware/middleware.dart | 11 ++--------- .../middleware/state_management/bloc_middleware.dart | 3 ++- .../state_management/provider_middleware.dart | 11 ++++++----- .../state_management/riverpod_middleware.dart | 7 ++++--- .../state_management/stateful_middleware.dart | 5 +++-- .../generators/symbols/pb_instancesym_gen.dart | 12 ++++++++---- .../pb_file_structure_strategy.dart | 7 +++++-- .../provider_generation_configuration.dart | 3 ++- .../services/pb_visual_generation_service.dart | 2 +- 10 files changed, 43 insertions(+), 28 deletions(-) diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 12b529f0..24e33323 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; +import 'package:recase/recase.dart'; class ImportHelper { /// Traverse the [node] tree, check if any nodes need importing, @@ -56,4 +57,13 @@ class ImportHelper { return imports; } + + static String getName(String name) { + var index = name.indexOf('/'); + // Remove everything after the /. So if the name is SignUpButton/Default, we end up with SignUpButton as the name we produce. + return index < 0 + ? name + : name.replaceRange(index, name.length, '').pascalCase; + } + } diff --git a/lib/generation/generators/middleware/middleware.dart b/lib/generation/generators/middleware/middleware.dart index 486f9400..d668962f 100644 --- a/lib/generation/generators/middleware/middleware.dart +++ b/lib/generation/generators/middleware/middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; @@ -10,15 +11,7 @@ abstract class Middleware { Middleware(this.generationManager); - String getNameOfNode(PBIntermediateNode node) => getName(node.name); - - String getName(String name) { - var index = name.indexOf('/'); - // Remove everything after the /. So if the name is SignUpButton/Default, we end up with SignUpButton as the name we produce. - return index < 0 - ? name - : name.replaceRange(index, name.length, '').pascalCase; - } + String getNameOfNode(PBIntermediateNode node) => ImportHelper.getName(node.name); Future applyMiddleware(PBIntermediateNode node) => Future.value(node); diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index ba428645..cf95f3ac 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -136,6 +137,6 @@ class BLoCMiddleware extends Middleware { PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); return fileStrategy.GENERATED_PROJECT_PATH + fileStrategy.RELATIVE_VIEW_PATH + - '${generalStateName.snakeCase}_bloc/${getName(symbolMaster.name).snakeCase}_bloc.dart'; + '${generalStateName.snakeCase}_bloc/${ImportHelper.getName(symbolMaster.name).snakeCase}_bloc.dart'; } } diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index e27a0d5d..111863ca 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; @@ -38,7 +39,7 @@ class ProviderMiddleware extends Middleware { if (node.currentContext.treeRoot.rootNode.generator.templateStrategy is StatelessTemplateStrategy) { watcher = PBVariable(watcherName, 'final ', true, - '${getName(node.functionCallName).pascalCase}().${widgetName}'); + '${ImportHelper.getName(node.functionCallName).pascalCase}().${widgetName}'); //managerData.addGlobalVariable(watcher); } @@ -47,7 +48,7 @@ class ProviderMiddleware extends Middleware { getImportPath(node, fileStrategy, generateModelPath: false)); if (node.generator is! StringGeneratorAdapter) { - var modelName = getName(node.functionCallName).pascalCase; + var modelName = ImportHelper.getName(node.functionCallName).pascalCase; var defaultWidget = node.functionCallName.pascalCase; var providerWidget = ''' ChangeNotifierProvider( @@ -79,7 +80,7 @@ class ProviderMiddleware extends Middleware { } watcherName = getNameOfNode(node); - var parentDirectory = getName(node.name).snakeCase; + var parentDirectory = ImportHelper.getName(node.name).snakeCase; // Generate model's imports var modelGenerator = PBFlutterGenerator( @@ -115,8 +116,8 @@ class ProviderMiddleware extends Middleware { var symbolMaster = PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); var import = generateModelPath - ? '${fileStrategy.RELATIVE_MODEL_PATH}${getName(symbolMaster.name).snakeCase}.dart' - : '${fileStrategy.RELATIVE_VIEW_PATH}${getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; + ? '${fileStrategy.RELATIVE_MODEL_PATH}${ImportHelper.getName(symbolMaster.name).snakeCase}.dart' + : '${fileStrategy.RELATIVE_VIEW_PATH}${ImportHelper.getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; return fileStrategy.GENERATED_PROJECT_PATH + import; } } diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index b3279294..4451b85b 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -30,7 +31,7 @@ class RiverpodMiddleware extends Middleware { managerData.addImport('package:flutter_riverpod/flutter_riverpod.dart'); watcherName = getVariableName(node.functionCallName.snakeCase); var watcher = PBVariable(watcherName + '_provider', 'final ', true, - 'ChangeNotifierProvider((ref) => ${getName(node.functionCallName).pascalCase}())'); + 'ChangeNotifierProvider((ref) => ${ImportHelper.getName(node.functionCallName).pascalCase}())'); if (node.currentContext.treeRoot.rootNode.generator.templateStrategy is StatelessTemplateStrategy) { @@ -54,7 +55,7 @@ class RiverpodMiddleware extends Middleware { generationManager, node, ); - fileStrategy.writeRiverpodModelFile(code, getName(node.name).snakeCase); + fileStrategy.writeRiverpodModelFile(code, ImportHelper.getName(node.name).snakeCase); return node; } @@ -75,6 +76,6 @@ class RiverpodMiddleware extends Middleware { PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); return fileStrategy.GENERATED_PROJECT_PATH + fileStrategy.RELATIVE_MODEL_PATH + - '${getName(symbolMaster.name).snakeCase}.dart'; + '${ImportHelper.getName(symbolMaster.name).snakeCase}.dart'; } } diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 492f69f9..2081ef94 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/flutter_file_structure_strategy.dart'; @@ -20,7 +21,7 @@ class StatefulMiddleware extends Middleware { return node; } var states = [node]; - var parentDirectory = getName(node.name).snakeCase; + var parentDirectory = ImportHelper.getName(node.name).snakeCase; await node?.auxiliaryData?.stateGraph?.states?.forEach((state) { states.add(state.variation.node); @@ -43,6 +44,6 @@ class StatefulMiddleware extends Middleware { PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); return fileStrategy.GENERATED_PROJECT_PATH + fileStrategy.RELATIVE_VIEW_PATH + - '${getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; + '${ImportHelper.getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; } } diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 42d8e9d5..48220fda 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; @@ -97,11 +98,14 @@ class PBSymbolInstanceGenerator extends PBGenerator { symName = PBInputFormatter.formatLabel(symName, destroyDigits: false, spaceToUnderscore: false, isTitle: true); - // don't include ourselves only child symbols - if (!topLevel) { - managerData.addImport( - 'package:${MainInfo().projectName}/view/symbols/${symName.snakeCase}.dart'); + var path = 'symbols'; + if (masterSymbol.name.contains('/')) { + path = ImportHelper + .getName(masterSymbol.name) + .snakeCase; } + managerData.addImport( + 'package:${MainInfo().projectName}/view/$path/${symName.snakeCase}.dart'); // if this symbol is overridable, then put variable name + null check var overrideProp = SN_UUIDtoVarName[UUID + '_symbolID']; diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart index d7561ff0..123f0ba8 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy.dart/pb_file_structure_strategy.dart @@ -56,8 +56,11 @@ abstract class FileStructureStrategy { _screenDirectoryPath = '${GENERATED_PROJECT_PATH}${RELATIVE_SCREEN_PATH}'; _viewDirectoryPath = '${GENERATED_PROJECT_PATH}${RELATIVE_VIEW_PATH}'; _pbProject.forest.forEach((dir) { - if (dir.rootNode != null) { - addImportsInfo(dir, dir.rootNode); + var rootNode = dir.rootNode; + if (rootNode != null) { + addImportsInfo(dir, rootNode); +// if (rootNode.) + } }); Directory(_screenDirectoryPath).createSync(recursive: true); diff --git a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart index 476a567c..07425aac 100644 --- a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/provider_middleware.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; @@ -50,7 +51,7 @@ class ProviderGenerationConfiguration extends GenerationConfiguration { node = await it.current.applyMiddleware(node); if (it.current is ProviderMiddleware && node is PBSharedInstanceIntermediateNode) { - registeredModels.add(it.current.getName(node.functionCallName)); + registeredModels.add(ImportHelper.getName(node.functionCallName)); } } return node; diff --git a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart index 375a5607..3cf24849 100644 --- a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart @@ -95,7 +95,7 @@ class PBVisualGenerationService implements PBGenerationService { smHelper.interpretStateManagementNode(result); } else { smHelper.interpretStateManagementNode(result); - //continue; + continue; } } From d6e4cfc3952c4bd48f6b5fb75e90d2ac499a1280 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Mon, 24 May 2021 21:11:39 -0700 Subject: [PATCH 132/404] removing redundant color generation for container --- .../attribute-helper/pb_box_decoration_gen_helper.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart index dc7013b8..aca43a24 100644 --- a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart @@ -13,7 +13,6 @@ class PBBoxDecorationHelper extends PBAttributesHelper { if (source is InheritedContainer) { final buffer = StringBuffer(); buffer.write('decoration: BoxDecoration('); - buffer.write(PBColorGenHelper().generate(source, generatorContext)); var borderInfo = source.auxiliaryData.borderInfo; if (source.auxiliaryData.color != null) { buffer.write(PBColorGenHelper().generate(source, generatorContext)); From b3155a0355d90f9a4c62e90980482cbbac8a4555 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Tue, 25 May 2021 15:28:15 -0600 Subject: [PATCH 133/404] Modified the protoype linker to add the destination as a dependent for the start location. For example, if page 1 has an element to an element in page 2, then you have to import to page 2 to route the user correctly, therefore, page 1 depends on page 2. --- lib/eggs/injected_tab.dart | 4 +- .../generators/util/topo_tree_iterator.dart | 4 ++ .../pb_prototype_aggregation_service.dart | 31 ++++++++++---- .../pb_prototype_linker_service.dart | 41 +++++-------------- .../prototyping/pb_prototype_storage.dart | 4 +- .../entities/injected_container.dart | 4 +- .../interfaces/pb_inherited_intermediate.dart | 4 +- .../interfaces/pb_prototype_enabled.dart | 6 +++ .../pb_layout_intermediate_node.dart | 4 +- 9 files changed, 56 insertions(+), 46 deletions(-) create mode 100644 lib/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 27ea76d5..4193026a 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -6,12 +6,14 @@ import 'package:parabeac_core/input/sketch/entities/layers/symbol_instance.dart' import 'package:parabeac_core/input/sketch/entities/layers/symbol_master.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:uuid/uuid.dart'; -class Tab extends PBEgg implements PBInjectedIntermediate { +class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { + @override PrototypeNode prototypeNode; Tab( diff --git a/lib/generation/generators/util/topo_tree_iterator.dart b/lib/generation/generators/util/topo_tree_iterator.dart index cf2bd220..997a736a 100644 --- a/lib/generation/generators/util/topo_tree_iterator.dart +++ b/lib/generation/generators/util/topo_tree_iterator.dart @@ -32,6 +32,10 @@ class IntermediateTopoIterator } } + ///Calculating the in-degrees that are comming in to a [PBIntermediateTree]. + /// + ///Its traversing each of the [PBIntermediateTree] in the [items], documenting + ///that the in-degrees of each of the nodes. HashMap _inDegrees(List items) { var inDegree = HashMap(); items.forEach((tree) { diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index 3c5ce073..ac6aab81 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -2,8 +2,10 @@ import 'package:parabeac_core/eggs/injected_tab.dart'; import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; @@ -16,7 +18,7 @@ class PBPrototypeAggregationService { /// List representing [PrototypeNodes] that have not found their /// destination [PBIntermediateNodes] - List _unregNodes; + List _unregNodes; PBPrototypeAggregationService._internal() { _storage = PBPrototypeStorage(); @@ -31,19 +33,32 @@ class PBPrototypeAggregationService { /// Iterates through `_unregNodes` to find whether any [PBPrototypeNode]'s /// `destinationUUID` matches the `node` UUID. If there is a match, populate /// the [PrototypeNode]. - void analyzeIntermediateNode(PBIntermediateNode node) { - if (_unregNodes.isEmpty) { - return; - } - for (var _pNode in _unregNodes) { - if (_pNode.prototypeNode.destinationUUID == node.UUID) { - _pNode.prototypeNode.destinationName = node.name; + Future analyzeIntermediateNode(PBIntermediateNode node) async { + if (node is InheritedScaffold) { + ///check if any of the [IntermediateNode]s looking for a destination contains their destination. + for (var _pNode in _unregNodes) { + if (_pNode.prototypeNode.destinationUUID == node.UUID) { + _pNode.prototypeNode.destinationName = node.name; + _addDependent(_pNode as PBIntermediateNode, node); + } + } + } else if (node is PrototypeEnable) { + var page = _storage.getPageNodeById( + (node as PrototypeEnable).prototypeNode.destinationUUID); + if (page == null) { + _unregNodes.add(node as PrototypeEnable); + } else { + _addDependent(node, page); } } _unregNodes.removeWhere( (pNode) => pNode.prototypeNode.destinationUUID == node.UUID); } + void _addDependent(PBIntermediateNode target, PBIntermediateNode dependent) { + target.currentContext.addDependent(dependent.currentContext.tree); + } + /// Provide the `pNode` with the necessary attributes it needs from the `iNode` PBIntermediateNode populatePrototypeNode(PBIntermediateNode iNode) { // TODO: refactor the structure diff --git a/lib/generation/prototyping/pb_prototype_linker_service.dart b/lib/generation/prototyping/pb_prototype_linker_service.dart index f5898c53..f549017f 100644 --- a/lib/generation/prototyping/pb_prototype_linker_service.dart +++ b/lib/generation/prototyping/pb_prototype_linker_service.dart @@ -1,15 +1,8 @@ -import 'package:parabeac_core/eggs/injected_app_bar.dart'; -import 'package:parabeac_core/eggs/injected_tab.dart'; -import 'package:parabeac_core/eggs/injected_tab_bar.dart'; -import 'package:parabeac_core/generation/generators/plugins/pb_injected_node.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_aggregation_service.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/services/intermediate_node_searcher_service.dart'; class PBPrototypeLinkerService { @@ -28,7 +21,6 @@ class PBPrototypeLinkerService { } var stack = []; - PBIntermediateNode rootIntermediateNode; stack.add(rootNode); while (stack.isNotEmpty) { @@ -41,28 +33,15 @@ class PBPrototypeLinkerService { }); if (currentNode is InheritedScaffold) { await _prototypeStorage.addPageNode(currentNode); - } else if (currentNode is PBInheritedIntermediate && - (currentNode as PBInheritedIntermediate) - .prototypeNode - ?.destinationUUID != - null && - (currentNode as PBInheritedIntermediate) - .prototypeNode - .destinationUUID - .isNotEmpty) { - addAndPopulatePrototypeNode(currentNode, rootNode); - } else if (currentNode is PBLayoutIntermediateNode && - currentNode.prototypeNode?.destinationUUID != null && - currentNode.prototypeNode.destinationUUID.isNotEmpty) { - addAndPopulatePrototypeNode(currentNode, rootNode); - } else if (currentNode is InjectedContainer && - currentNode.prototypeNode?.destinationUUID != null && - currentNode.prototypeNode.destinationUUID.isNotEmpty) { - addAndPopulatePrototypeNode(currentNode, rootNode); - } else if (currentNode is Tab && - currentNode.prototypeNode?.destinationUUID != null && - currentNode.prototypeNode.destinationUUID.isNotEmpty) { - addAndPopulatePrototypeNode(currentNode, rootNode); + } else if (currentNode is PrototypeEnable) { + if ((currentNode as PrototypeEnable).prototypeNode?.destinationUUID != + null && + (currentNode as PrototypeEnable) + .prototypeNode + .destinationUUID + .isNotEmpty) { + addAndPopulatePrototypeNode(currentNode, rootNode); + } } } return rootNode; diff --git a/lib/generation/prototyping/pb_prototype_storage.dart b/lib/generation/prototyping/pb_prototype_storage.dart index 1dbe93bc..021596f9 100644 --- a/lib/generation/prototyping/pb_prototype_storage.dart +++ b/lib/generation/prototyping/pb_prototype_storage.dart @@ -29,7 +29,7 @@ class PBPrototypeStorage { return false; } - PBPrototypeAggregationService() + await PBPrototypeAggregationService() .analyzeIntermediateNode(prototypeNode); _pbPrototypeInstanceNodes['${prototypeNode.UUID}'] = prototypeNode; return true; @@ -39,7 +39,7 @@ class PBPrototypeStorage { if (_pbPages.containsKey(pageNode.UUID)) { return false; } - // await TODO: + await PBPrototypeAggregationService().analyzeIntermediateNode(pageNode); _pbPages['${pageNode.UUID}'] = pageNode; return true; } diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 73bf4267..e79c8d7b 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -2,6 +2,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; @@ -9,7 +10,8 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class InjectedContainer extends PBVisualIntermediateNode - implements PBInjectedIntermediate { + implements PBInjectedIntermediate, PrototypeEnable { + @override PrototypeNode prototypeNode; InjectedContainer( diff --git a/lib/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart b/lib/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart index 00ff9541..23327ba8 100644 --- a/lib/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart +++ b/lib/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart @@ -1,9 +1,9 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; /// Interface that defines that the node was derived from the design files. -abstract class PBInheritedIntermediate { - PrototypeNode prototypeNode; +abstract class PBInheritedIntermediate implements PrototypeEnable { final originalRef; PBInheritedIntermediate(this.originalRef) { diff --git a/lib/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart b/lib/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart new file mode 100644 index 00000000..003f4439 --- /dev/null +++ b/lib/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart @@ -0,0 +1,6 @@ +import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; + +//TODO: refactoring it into [PBIntermediateNode] +abstract class PrototypeEnable { + PrototypeNode prototypeNode; +} diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index 13ab2085..de4851ce 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/exceptions/layout_exception.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; @@ -12,7 +13,7 @@ import 'package:uuid/uuid.dart'; /// This represents a node that should be a Layout; it contains a set of children arranged in a specific manner. It is also responsible for understanding its main axis spacing, and crossAxisAlignment. /// Superclass: PBIntermediateNode abstract class PBLayoutIntermediateNode extends PBIntermediateNode - implements PBInjectedIntermediate { + implements PBInjectedIntermediate, PrototypeEnable { ///Getting the children List get children => getAttributeNamed('children')?.attributeNodes; @@ -29,6 +30,7 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode ///Getting the exceptions of the rules. List get exceptions => List.from(_exceptions); + @override PrototypeNode prototypeNode; Map alignment = {}; From 2d8b863e6ee739123a02de526173611db0a63dd5 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Tue, 25 May 2021 15:30:39 -0700 Subject: [PATCH 134/404] test file updated --- test/assets/SymbolTest-simp.sketch | Bin 26493 -> 26536 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/assets/SymbolTest-simp.sketch b/test/assets/SymbolTest-simp.sketch index 5e3cbde60e11292502bc9b9d92eb07db273056af..699538adc2e8bc2cfb78c4543a5b157a114eabd8 100644 GIT binary patch literal 26536 zcmeFYWmIEPvn`6dJ5A$GT_ySux)L*q`P!L@OBZyXwTg1ZG8cewO-&K={O_v8J4 zY-H{u+X=^6Z8)crH-4p`wz)Kpy zP4ZC8fK)?)UC9&(=AtqQz&V`r_@v>MUH_0}3MU>3HI-o_Fw}b*WTufSv zUBsT8S!w}X?%q}%H8C>KuY_AmQ_h3qEP#g>6fB|YW!>b5QU|7jOB+Gk%`{EQU#9B~ zUhE*5EwR=5TMVoqjJW(KGYFU8S`@`UK9~`+MrOl>=^QFgHl~LdtO9RKbGI0?^c6W6 z6xWnrR~CK%6seg2COUD`S%(N0IZO>k6CPJMH|C9Bmlq4i$l0b9V+n(U@|fbIBz@Bo z8wAM|LM8sfN=-piMXGKpt&3&nCf{O-vVM_oB9a(}-<9<;({`fCJg!TfLmcvfb5`Ee z5P;?(T$9HmtZL;ZNvjiIw~ni#lS(N5=Av;bga;(M!ybnh}Hc@HV-2~4USD8 zH)@T}OGpB<{>&yJnk*!twujCm8zJ()5fU0?M?LCEZQZ9cdFSBJL>o3fd0@Se(`8A%e=9M5Xv5J)DDZQIDD`g)X_nRS26w_S{9*#AXUYWOH#?oX(E%a zac5NFRE$2OR2jdC8pMVZ(_{zCXOLniP6l71XZ3>|s(iyqQ-W?uwWKLjz$l^_NyT_} z#AOhy7WfcuwL}BKpcz4_kf>KM_>(0rIKPQd3{`G#zj+FW8Qv_oYwJ%NV0)VT&#udR zVjs1>9ab@~hC<+kXj5d-$F=J((e*qgg(PhI9byb>#ZS(v}o33BOaSAvVx zLH?kfNHSK^2wrkY9$-+=HU^+SoKBNNB#3vISwY;H=IVi!x4dAZ6Jv z_-Qi&Y&_l|DEzJ_9L@DLQ?7>`cDJHWD)>{+m6LOmx9gQg2TaJPGJ;KnSc^r;#HAsX zlG(ysIKA~3h{vC=9qL!@+p4n~0@V8hi(Da=CrW<-d>>v7CaL;%fY@kL0QAeU%IC1M z7I1_Y^K9(PvI8@>0Cl-^O0@^2$RXaUE?-mli&RmDXY4Z=8_7X$( z%8r$DGO%)sfq^fPQ)e>T9}R3hrl-^b)OPH52yGcy696s=$m~BY8jy$EF+-ALnW5`{ z=ex2%I`_BnT#^l>i`61T=t3ZGIoQjy^XW#HcIQmzo>nc+YA>!zea=Ue(&|hFEi@-$6G*Re zbR{pPA65-SfSrEh+vAb(~mZo{;`f$MM^eE z(B<|YZ_~!zvq*-LgOBDvm=lJ9Lx-y15c#o~2<1HlyGIoJf}h041Mw6oH7v>OK#w_> z7uJqkhY%f-_SFXVI2~o z3&eR8VjYS7sG1htQ>ej;hql5G#GJn*mI5i^_&4{1OPRQy?C|*(b6M!{siV=zi}S?^ z-QJ{^ml%jV=z;QClcjlSvS^HnEJ@(+JfU{%=(N}py9N}6ASn>HmO1&0K1YnGw`p3Ve$%JP}{;h2RKnp#96 zc-Sjee~>6eZDdfh3jBa1Ip+gyt?W(>RhF$ z>;qmQGb|-j>R4$Cei1p#0)ewuWFUCRL4v#YQS?>BnNLraJnx`AxfXMV*I?v8B&=*A z+b}6Z<`D#jQp}x_DJsW3n6y}&z`{zXqn}Ve?>sPDV}sCE0HxF(NSv+KJiI0jH>hla zRwhV7m?^^IRa^g?UDD4*#a$8f*moZ4X1w*peqdAtC*GzP5cBE-kcxkfL^6$rB`jC2 zn8w%M5$k)xW*?`4jj9t%L(Jfku*^){D~MPan{(I>aN-^3JiraD$UbRXEWxBF(5yx4l&7urAZ@Q zK(I%ySDxJlvGr0XW9)D%#cGWLWCe*6$)m}>wzXzRHF}5otY{L)n+2HuYW61&MAh+m z^D_#mABOrq1&0pfqF#}(yYt4DAfm(k^X^R!eJa9 zH4=>M3DzQAVkxJBgPkcW^~ZIv3+hx1Akbyd4JzAW+3vTBcBWGsr<5dj9Rq@z3`O2+dJzOt6A$Sm#1i zxa|p}sb7(@2?~jq_>tj}p);}MitPERGGFl1k*;M`=&cjQqh@_f^YP6eYNd$DO@NQL zQ*km;#(6@nyUa$W6kk^(1xy4Zk3|N>hf?^sK~f#7tR6(hKB1u?Frw|rhD&; z7UIUv1t&dbu^!~^n=HHEnUwwq!LAkE?u0@C1G9+%17rFm*iOcl=B`X^Vw@su;_O@u zqTD><4D76|5)7geV&V*JoUA;|>};$Y5?tK>MZxuTU4h&U@84(z2#D61yve~#sE_10 zRqH+Pcm8NZCt1Z1WU47IP~`snc(G1gnDk(cHsxuF@OGjAgUS-#8(2Pux%K{};S)G9 zvlFxYeA7}=MKX6aJ|A0t>s{B0quFv9M+n;X{JTF(M@y&3smlAam6Pa@QM+p^v~yD( z5503ZB-G;#$XwXza0(uODk@ZNMZfNKRRCru8tqy}f!W$Dc}FREl^u_bbO1XKw#(Ko zhv+MXDW=6oF~L>Y$7(ICOUtKYb5$l%<23!lJEoyR8KKEW7YKX9DN;=0xbbrc!C0Jh z+{?;UlLgAIQz$(F{iB%O=|X-_^>(Y%DjE@^G0u~-@zaVEL(Crf(nS}}diPv^uN(%! zHd_9+G^h5_GtC2S4xcA)_8P|c#)h`hhNoAr+1S}#vCY^rD?#1d5viI~E1_3}&^Z(+ z)R6HY1`J8+NX!Z4LO7|-QHt4e)2QvD%E}_;ciQ_~fcH;F^l$p8e;rV64R~@H3K9aM za_(&)B;GHD{BdiD4STn&_4TT@Dk^E!?j)9)5=1&J-GKwTpv8RgnLl2OfZio_zpBc% zTI(#_qxn+%BU2XZQc#&9XzTkU;$3_ZtMJiCkH5Zr2Y7}BVryzojl-by3l#E#I5RbtbQ);XgM)o{jlj{fyHP_dc{S!o$J^w=DeH!gc8x<* zWd-57)(IK}xzLA3^KNog09rE_1Dn!joM6HYMnwch-c>!f4|rfr{<;MA3q9?$W%s># zib?x1a60S2W?V#7o_at%JL%5M_G_!|*4Qd~5dbE|j^&NRRyesqGpg{9KBv$LFRmy2 zhbr~~o%x1At=OK8#v*e}7VlIuXxP)$;VksQeIb(7&~1$?-n>y_zGu^IwYm3ZNmIYz zRn;|_3)$_}A?C=PGY@C)N2dl={P(Y0sj})fc6#jT`adj(?3Q}JE2nw;vrbYijtH99 zKe;rk3|&RcTkA7SmsKk8M>x7>XfHObq95IjRmQ}aV{Y**cn83^9uwmK=a2-N&#N6=3O&8j>rQ12 zn7V83%|j{BEst88A?834cxc`3bIx*8(7Kd^-@3(<=Sau@N=l{~j$-x`o(2~{jn3_> zxbB#u1|EB}j|*aN0H)V|7JpT&?C^hyIiHugI+8`5c)!8@%Q@9orJi}#K|Ck!3vS~G z54&*$0q0zYv!e#xFG{kMGJ@J-hTP()>G&K{cP0(g^dVTlc++osY&T*k91+Ja;->!k zhm^`yocFK9xfWanT#Br1EHqUjCCad6DkM*z92-BSFgP5{o0$=Hahi5~s7f?HxVRwB zwQ|UHT&aUCdEsWqv`%qP)CPKi#f^2#>4?^2hRrw>M>ZN|`)}6YhPmnXX?>EW7BuK8 z-z#>D0ZsTyO2>Dh&uGj6M6gs$fHMyFsC@bS`k2@BF8)hUOJhgJ3X;dyQ}q+~UiQTf zuqbF8d5+$tfl5mS5=7ZQl@j$Zsc)UBRlZ5LIg)+6n`QXd@npkJ%($Gcrbp=3;q6zWhmzXZh}(`S zUBKg$UQX|Js~6nlLqd&+=CwrkHEWg$#UQAm!Ab!<3&CJY2LNficJoU9{a5B*Z(xlu zXP!kM)?&k6jQw!)1u@f^(6yndm%+!H%~J?4L(`IR|6)`ksuV%PXGSKMhAZ-1ku z;Ij}$9Ousy&v+(xgg>>un||E`+Gs22eY-I!i>lFL=XCfPoz*)Jj{e}F^CSpQ&mEe< zNvp+ME`g&OlU={WM?3$sL6?E>mB#bEQ@>>XLjGZ0sSvg8Ve1QIqgB9Q`ZVqbz;Jlq zB#9nyy7jjCxH!MDLw(qBwE((mbZm(##iyrYP;|UwFPRHIkWj9W7B&jkE@r@vRK4&r z8fU4Id;zEgCkbPQCYh*_U+~1)I415#%|;dCbeb`jguhh_+_%Q-7zwl&cmWoENts%i zCbP@ycNubef7?7ux${)I{X&62vc+p(*1$G;^<<)ldsA9u%%^^L49j+7vYEf!7oLXe z%-IAq3?uq3L034R>xVhZ77U zD~oXR$|0s;p4m@>E-4@+ynD>Q*P+0)RL4mFHS%s;eH2?iiC?JVsNf9)X@YFqYsYU@ zM~XdUyXpFKwH4ku^3+$q6p<%Y2)^q{P--d5k+6F2#WW zmb=DQ)Si6k6x=G`BluN%q0%czUmNslcHlL?nA6y@H#3ge9~4WIiZ+OuT1a6O7mJf@ zExpIyVNuyrjr;Z0@x@_PYM8kxlq+?sG)ncjDUPmdh#T+drKSIS+7SSD!!Y{ z!YjMzsd1EO+U7+bJyRpSQ2V|FK_;R^-=(QlsyIf_=;Gf?8yKI%-PUt?{H*b+l$$mv zTipf)LJlJ*VwMUoHDcf%$0F6jB!Jm^Fe2cW+TtpZEM=vnk*|`_GYO9kQ4IbT?rzfd zeN|Nyh&;VYYy~^=Fu>hYYky615lOB_25>?ar-L(7?~5!BgQcUr2@V{fLe=2BLh=2{ zyHn619z+Exh92G_ETAy2krE-F+ixiN2n8GXw9Q0(IQ;qadJx*{_cuLo)leaFIT(?m zdIyd<4N}{^Ppd?RoZ!m(_kV0ZX5U?Qx<)iu#qps9N>&Of!s`KvYhmzX=DWT9KV{=g z7trGg900`8o{z9c#M6U;sH*aJ&i++IfmMxzE#5`Epm)4S|1SYsW z`+%No^E=h}-)&rCt`k2LvC*?_#M%?Jnq2SGMv<@elL!cU*F0eyf59SdJ~p)Q*ChFE z2PF`!x%`bpMHq%jKqv0QGC*S$_d`M_ZWZ?{W`&2RM)3~j*wy%6TyGj#tN?3jE?eav z8JQpuI}0i4cRv5TK_(b09}2Z7B1wtod_mi=&hyhKK@~$RNZrdPop8pnvGF5qmdM9d z3Tel`3zi-%qWiQDva003IFmLhu18_P zCFfTmNBf0`278{ZKE+H0TTGbf!BnhoD(eVv$GGQ{^n{-=z{dmLRdYK|w(d{@HUmRNg$lD>2hL{w=C+P{< zyEcAnE$R8aLves1tcn=QjR<3H!!9eai}|H#286#MrVDsU4D+>>Yo>F=W$!dyQG~lhB^?bZh8{M1 zSb?M(PDFuKSQ8UWe$okYduxbM@UO&Tzb>7cO`$pl8keBKl_kH)AMJFXOsMkkP=o=I zAEYkk+`pK=s^J|DJ1H6e*C`5}A1EKoVUvjO|;*njMt zjzSS`Gw4b))IwY(@hQ&+b`n4hLf-}8RnP|Ky#Nsn;H4or(pu-3q2)&uNQaAcEF60G zT>tz2P{sJ7TX2r{;;&f0CFsm9qaX6Mo_3e_oiVLZ<~5ZhA{3R(+Fvi?e)w|W67}eO zv+}O9y&f`r#JK|fyFjAQ0e;9DlF4}Dp!H6>cZiVNGH=n!cK>@v61x4J`fV#(&b*G2 z&-U?U7)zx%|415@cj%35sbGfLs<;1WsHJ@v#**w967XIB_)jP z{JN?W4N;%}GpdChAI(E}#W((WGv(JM_MJaL;2Rm3FCi8St)zyR5jG0g3PqoJC8Qhhx?-Zn|33w#xCFB}2R9o#gBS}pHv>D5BsT+(s3Z@A z7#AliGbgJ!Ckq$He+f!0eb?eP?6+@>xz+F_iD6rbL9twWUN+}B{1mE;`1|1*lKLdW z7w&g~)7Ud@)}0NVGE|MK2k8zo%K{IZMMd9ovjJUc`bXJ31nnwQ<*LU7{x6EDfE%bU zDGTzV;gA&k!%Ar8ND}-piTQ(`QF&+y;mju*XF6ktE=4-lbQ|23qkQfajFm*{&ecMi zr^ZFPd)XUf9jaoA`u3a^UbVne+zmYK-t(6#9o2)FTvXm(%^{J2ql!ug+k@=PmWXg2 z2lbbNQ@Q81Bzf?bR)S+U#T?0+o&NT<8b^2kYTmtA`y=wgPJgW5%lYb=8fl?V5JUCK))GfyVj4DL|1gr&QQI6`FS0H65B2H17$>kil%;ws!D zXr!l?^szGUXFE_w^^z1P>qbopekn*Hr_;mfsm}mW8=CEDvo)c*Wq$Za*{7(fmStP< z{)M25qL?sni4$PFv2Fn?YAnz_GlUnf;<20WZ&1Sq^no|A<2lTX8K6fL4`Y^xM_?ra zpC$|5Rce#LsiQz*mQ#^;CI$K~PI+r-4qJSE&t{v385v#r8t45h3nIw>lmTn|z<#3@ zQBEwhM0HKtXr8U#WwGy?d3VeoH#fI$8fCb;IZk`M>NE&+H4L=tF9Hk#?^b*KW(VW zI+__|g4(wA)t6J4)aQTQSN!}DkfGCYl)jN0{q*L(dK#d95!x2gihNGL0f5eqsl2)C z;95GWQa?qxpUFcFzbHkv(iF;ors!O3U@$=AnQ}^_U=b6oQ_DoBhX1GldrhtkRF1`0hFE*su= z@-XP^j6yo%%-YJXQq(`qy*9qdefEey;qB~~1pLG=+!DrJV+e?EbrFSlr_gP7-kDOE zUtC<+ilA-=SS=M~cj;01gOg`|cxR&z>IEmIBcw@W7ZV+kJbdVqd_1NcNm2Y5QvTu^ z53y^4rR+5h5v`9S6)b%Mg{} zv(>!lFhIAy<%4-x{2^y(a#x)jW7CNM_L9`#KUyvw|`BlQL`9)a|8+DFB zWs2fV?J~6zTX(8luL^5@yU8^Kr<( zA_Yr8r*qFIK!-Jlcly-dqu9e&UQ-^0GkPV+Ve?)R`7dM5;lr*C+5*zwN&A?gi+pNj z{Y?#mA_nJulX4kfql9WM7=0R&kuNa8v0Behm)kAvkm&|GSe&@EfUk3A42uAj3mN_f zZ|H~pB)jU#thl9fkb&x6hYp7=$&KNH2i%2Zi;MK&gc6~qZ&Dj&FX@M5IP$D~>761Ne=uvZ;7x9` zfh*)_!(e&Rx|kH;Rm-4A16!mdZ1kGgi)Y)e>dl-aqQzyt?6 zNl{GB!a!8BFaJmX8}4aG7yfzr@UrLi<! z@fh#dxMw`14-CZu=Z zO3?k`xg@f6MqeotHhEJ2nvM5xyYXNPyAjzrvWj2AYjKoTEm4IkYHtRD|4*7FG;i>g z1Og094(h*rXK(Ii{2$-tqK~?Y)2G0?~%#VEGTbBp6PE-e`jK?dPP^@?6Tdq zyGQy;$nrzXjm$3aTD2Vr1w@=COEX%XNsrfI3!q^bq%pFY1>nEG)!RsH9c&?L)L-d$yt88|Gl>qgaS6 zAe0GSsIpEFn{`ww8-8h-$V+Gv*7yR7057>*)r`fl>F)qh&Ak~AnV;3E$3^nt^yS&1 z!zK>-bA!&Ii{@a9U8}v{>tjrz`*kajvc#>2G2*4vHm2vxX-luJ;#QW{Mq^1B4~pv5 z%z_M;H_fn{b>>yf1fr|EyQ{A^XqGH#zes@Atxh*i9vyddK2RXV?3RlO`97<(+r^xv=zSi*T~(w+!D^z$-KIvqM!qTE7;B&q}PQIJK z+{R1>V+%HFz9-P1l<6_s#zxDj?5(Hnyw%HG&Lav1{*#}v%p^fz5O7%ZiS%BwRN`RZ zP-u}*a0;7na3n#(a^N9sRCp=mpB7Nmm!EG5lazw><738-p$mh7hon4wB1zCxgSKPg zhxb1LVEtph{~3W+*l8Hb)a4Tpw7oCzZ-PNA5^mEF7M@Rlu+ufsCmhNI0WF)QKjZ7? zxFp=(sQ=c%0u48nVI&v-2|&y4f<+Ss3(kOmvXo<{lKKREE(`MiF6;jXpB9~|f?-+; z6OWsPHX|2eoNzk=lAjg8MgKM=4ZtxKl92)T>2oVw5^f-aSJ=PkqY!q&85|V<=iE-P z{#A#5^3Tx8Cjk#>B%z`b{dE1>XJB|B5|Mt!2sAueHZ%(h`e!7~FbX@h=>GjT8jW<& zHhpAN)W4AN_{435Nc|g4&5cvXBo zz18Z3OSfsc;@~j>l3XX|#-B)Ig_<(imdNv0kM8rg@h|uf4n;^hOJtDgt-E?MGK?s>_#j*w~B?`HDGvCwhYH9qaCd{*t=rvU!;{3Ka95C@G6iYKMG0_<&Q1K(F*skM^Hj>(a>G zEa+7`)p_1wVoD~c&7+<^H=u6KW>@-R%WXCj{O3-L4%E@r&gXf(F|pqTOdm&_MhS|H_#&$ngJv1qF6kz^_oin>pv+=gTC9Z?A505?OLJ1 z&0~?=BwDS^UuISg2=>vRc)gm{9ZvxwCled;Nrf{|@ZZ=zd53S`s!rV9@3+CGO=PsH zx-81*PBd(u_vtZd#lpY09FaWrCZMJ`zFYMya5~9~B6T!m|J%Pr(c6EDn996DaTm6BbVKyoR|67XLL{+7G5xI z2T#`~TL`osKRLg33N<#na+^I2?4Qo}PzJVLPrJOBdybY+8&K`FuGL%JFu6&-`P`)d zn7SmWKy{v*>9It-I*fulwyYleZC&$NXYhPhx1DbhW9jcr#afMKf|NAEPH9HU(cRJ` z{0*WP>t$ZHx@ANz9eR(MF(rYQ?=F|Fo)fOBxk(9eL`=)M&fVvn9tkE)0qHm2n~Tkc zP7mf*)>jVPNb~$mA|{J3S(ED7zFTIB-Uq5$#caD790YvRHQSG%_4cpqkvKUSWa*rM zhs~xy?S0MHyS_m@Xhq#(>}@+LyG{l4(i1cK7%~bS(3Mx#q--|(-&T5-alS0wrFLZ9 zlRw>i#nwQh5HeTIyJ3$ZoRk&lY0vs()xX(^*}GS-e6jGTyF!*nb{QbC+FjR zcCdHs9^%Xyc7G+!lp9Y2BqZBMBqW``@(FHLk90ijt~$S&U21B2+H!Waxj}P-_qf@r z{-gvt`xJFG=^I+p&gG55n^MX0=A;>Jc~+XSf}|2O7i)j=5x;f&?d?~ZMN|(@5CIjF zL#c?!4BOr*${qE{$zc+H>N37J_gvs!w_3iFN%_6f@Z3Z;mXuadogTfG-0TBBTuZuo zjap&}?pWG)&Mzkn^E$p$#c$|8TfyZ842)g>5Sva^1bG*?-0<;OT$&z?EfXg!c?CL; z*&E3;4z2I>i0L&s;j#C{h7FR z{EcZHXx(w~`uF$ByUV+fo@+uX*3Lr$Dmebt6NQ# zgVtS=_tc}454*$pDCmHgX&tkg^rClyy2u&F3`gnHb&0WSeofi_x9JD7nnY0{cU{Ce z3=^6RDV04=`eoikH9I!O9-t3{Mb4gz2HAU}-h|ilORfoh#rJZ1zx#e=UqbQ-kat*1 zU~TsO#`HvMfM=W?i`8d~d-mbG;EQ3$bSsa}cfkW7^{D^!7K5SSA;hY~V1~lH`%#2v z_|jOKD?noHqs7hAqpM{Q3T_JHn{+*H*++B}J?(DNtu~^?*dYMfURU+Jt*gjwemPwG zW-Dd&#!><>9dQxh)kJG&o2S_QE{@g4=g_UnUPHNoQSE)vIse{ZGAWDC>7>PedCu=R z-`w|-+bd-;~pOCj%cEkA#l<=CM=ts5Y7ifBDJIlJFvz3u#df*D1OAokPm3uEBwGxws zoDc8mewHQPxU@FBN&6GW*~vzzF}uXRBsE|CV(71WamAVQ!$TYePvFD~R%>1lGhZ#qUL#ZZdfq(mk^)1wz^=-g< z_Ho&w3xjZ>K2)HE_I;-i_0CAC_te^md(Xkd{5vJ_#|p($;7E4ui}VLQy2wCD1Fy68mXqkK{B|-@b=sE27-Mal z8xrpC)nt@C{2oTfr9uIkIP^J8zL#wYelEX*XLUCJ@LY~QeB26n?>0*TeT>Qw1YYML zuU8cV7}t(6{7rg#?w_{|sgG>h{54S_R*hh@-rxTi9#m^PT2KS?FL4Gve!h>&NKFKH z64A>~%3uH4FWV2&N3{WL#RYa5Fmm6MweK$2t_^D&;qq|g`|D6pC^&78Va(M^2Xg?P@Pom!;Bb^f0QCYhGT% z-|foqR(n={OyJ7OqCy>fv5WI``XFtPToz5YdKn^ec%DRh8cT;61p=FLd6dqd(yw1( z1e@e(nG9Of<2a@qFdf#|v|4PeTfxrnHgcqDpzHi|T+`jUr{|`?-;8!%+6|_-p*pZ= zHm7PC0Xs6EM5FJ&GUqK6I26Pug9*;Jh5?6q{iL}8HZqEz#5(blSi@ym{C^s*k_*sA z=vv;wA;opzY(sf1A8dH#H0oNO3j`Rh8sDNkmlwdiy*`}H9!-^XakXztg4oVs75KHL zUUqnL1UFpY%X-Pk?_|HHZ}`ac-3q@RPku9ME@XRv!a?f>-J?m1xA4 ze7jx3U(#@^MCy(U_jg#Y>2O&7eLiJG%I9;eF>AhOC+P9S4X|uBz+vRm(yeaYu<8XI zR5uD53tn1cShuC(YIgMJMfr43}We zte|zuOPh)7VLrwIyAvZ>-*es}XLfFmEa7Z1CBSQ0J|~Mvz|PiMfulL@Y;mVYoYUpE z2WC;H)!LT|`*qyd5_*?JH9=RJ`0@j#a#Un(>Q?I^SXCF z&~oWfOG0pdDxsO@kz+7@V_*NR7pR^w^|+vYy|~Ae+U`R*4g299=(ft+snnqVGVd^Z zHP?hY#E5D6q6DJ5-0I%by&k_!cMm*&JXUd`Cib&&ODME6^@xcF5mByAQH3rsdGV{viU3PtAc|crZTXM)Twzcs{X?AxU z170oRudcr8GU>dY@0S%3=LPJI(QvmeFMA?Q-2}SDv%72UHQAc4S+pa2@F8|~yc*sP z+pp?ctzS)VNd~t8+XVK5aX-*E+~;e$pW+QL7aV$>CpNgGYB$V*@UuE)KU)1)>%4}@ zR<%bwzn zYrYx`e6i$FD+f$G_Vv8&KOW(Xd&b*#XXnhYcEm$VxGRQC|$?lup% zA9nm>T&7)FqNsCeF66MM$M0jx$alji_ZeA#%B#vcUh;dcPoxABK|)&Os!|?~3^Y^K zY|+6MxI8_(%O8}uf%mp9lP6p87S=C9pe2G;AUg0Oh^M31b<{#^KPjEa&UVS+#a1)p z<5i?g@(k^FB*mn2L5q%;Z(lWAmpZ#*py1Oh-P3EH z=J>M0mcnUebX}vXJ>N#RyJYUrB+r_HW5t5JW9Ot~_9yL=Y@MwuI*qwY`~Bolf^M1n zRQh&{7-KefUUI!S!M8Obuyt!N;@j&E^TOTTpqG-mBbD8bF{7%{Wa)ELnWnf$2eI;-?(Tt0fDgn6)d5=zFNe-uA2@R^?V@QQ> z->noYX{gced3*7^#gr(v)HHw=D6_q6@eb&RY&;l`;Yu$DI{0`t(T|R;ievL#G~IAa zJ>Mo>EI0zY`B(zX!p->$OUOtSL9=`alOL~p5h|JEqkOuz$v@*QBdO~ei3EDjYa7jC zo?)JbO9ssDBkvOeh5;$PAHn9dZjrWHkC5c-Vc2$^LFS*&?xA))@QaOsRirLOb@62C&$-6m9zuy zFxjVt_os~SV&@P3l;it2B;2l@%s8Lgee|2K(_zUD{6AdlCl2_d{-1U?_^duLAuIl? z3$=gZ))`|ZKDGPxXWsF)_Ja6_WB9~*7}I}N0unWYw*Pz|!2E}E_{6m$ntqn3g1bJa zHu#eJuiE7DDe&6$@nZf>jZMORGxrzjA5QlZ_kZA$h0QN!V;QW2W2G&Wf0!Mr%lb6G zgKVXn0#3ZbSV0iX(Q8XK%QB;)F-EAPEl_z zixKK>U!p)g)0_^)XE0unHOs0)$abewmntI@s6?AtA~W`(F`F|J)z7Ko4mktoTFZzHaa<<5#Bvz3|qr zv^4z1Wba;;EZp0)XvLbO;+h|weiB*2v80kQ0t zniU7hQ6Zvwo?)FYVPr05D9X!xWGrMLkSHnpc)x#UB7bAn%rJH# z1Kb~__R*SzEs}J@=vg39LE=>$iN&2t3Lc#SmDUASMcYV5yA9ma#*u^7Zy}B1XG_;i z8+qkYlO?R=sj#(4gJ?^Ps^n^_|Nzp)^U4f4)H!EOzaW1 znGK&(Vy+HhvwE{*Hw8>X-ZwZuT8=^csrp6HIfIQKlhLo#P8nEPZD1Ja8&`~31k(C?L(j|SvKs=SKuY!V-s%6bO zaXWaA`i(Ma#xN@?4w^}S0Me%;nJ9A-CCZ?~Pz{w%EkJHr11M#gcTse2`Ou({J>y4!tDmJhc#@#~WjMlmUSk|3@@N0iZC_nlQgyld{8U?^Dp@ zzoaks#?$EWgT7l&@zh}TDPQuAr~`*z@`DEHlPiMU@LO$?7XJMHy^$s`ZvtvztbDTz zjhm?Iba9xN-I-Uw>6%wh$VoEa3LRB{q#%SH5|}aohxTQc_K7(o63Q%cm_!5RZew z@I0Z@tb68{WjHt8d{*iQDgeRHI~lrTnW*!X7Vo?-g(}A-EJ_chbv#uCFTFaxiN{Pe zzSnZ7G-@`g*==C_P#z%nNxp}$uS{Uvp%aKK=!C4GZibPax9x!8(G6^OKNt;|HIKWX zo#`tV5Cu+N@#WPYar{NZ&oZb?>`G^>`Opo!T*d3=0XtNNW)A(G|ORW|E-`iVcr&F_OJ!I75VOALAu02rVR^&fcm#?%CS& z#Pix0o>p3tAdaomc>7q+MO&eg9k#Y+P{qcb-rU&df8xWI^6Q>B1+^*RCjo2I9FoL$ zP4d2oM2I2dSJfhBwi+A}>@q_*KH^%-g3Ig5)C|PORL{Sr{B34Q8s5SeM_Q(ZI?vAn zTK!|nm%kO?k4l!Wblpk2?wKymJx<${3&^H>Yw4({x*Paf2c3X_0jBG?+Sz7s3F$hpq#;bC=asg?v+O6khZe6$c zv7NQF@KWR!7|mueI-T!LPBlv-<(~oc?D-pF+Cz1vK>~2!L1k^*H_6-M9Zi%mH@Ok^ zrR=Dc$#s#Dwj8hg#^IxrynVQtvHRT-$2CQzJB73Do+C=ILyoWYqrfJ!7IYji+XVBg z8Tgu}@Jl{R!oyP%_`38!(y8HKdxa$M*-N-{;0B&I92X=VTlF@%-bDOzEJqFjgNmx?DIX zPHUdGbfcV_5}f(CP2t4x!MD!Upym9iAk6hthjc(h}HR z23=gP&-ByVA+Ov+0uQ^Z!GR7jhk<7mpf&Q#7GILn6vohMLMdJJwJyTg2Gx4J@lPH{ zzqRIXHpU0qTgY#mTs-yHMRf*(=N0Gfs(p;;Y%rCP7Ea4-p)_i}Ol&-cz3&PcQg$oY zMM9Ld8}hD6Sp)VsUbti?1LWuadNo%)eYZbj>aBrZqq0A^Z_#Pa6&a{F;mPSmQRYiq zu!Xgq4&mK0vYlSE%_@;eua!~dEaK5G=r^~mUM=u>Iiwk_xK*P^Y&ln|CbfUz0l9tS zLrbmap9gDx>)61zSu7HHsIO^PJ*w=te&PG(p66l%%0%*DtOi9}`ADWeQEqVAz0J#m zDsr-lRO>tDIcq`M!GlrMIdktQXRGF`R@I*^vO`ILr?O>LSvC7cfpsY?L`A~#z#@UM zm4JlQ@|;^W{W4lL_-Q%M{r5b=bCQVaA$Q&gWmm2usWMD|VA+I1Z^2ek^K5f}R*uvG zH}bi=0(a{{)Y8}Giyxy3ojsQ=oVnW7|Es+#4Qgu3){0DC0ku(35D`&OhD1~bnP)^q z5Kx8?RAw%dKnOBlz3Ex@+&IqGrL%Uk)bfppe=oU5?<<`mzuZN?j za^Qu8mpE)XcT&eE{ORl)j>Iz3G&ZOJ&T& zHG!b2gA=dAj~d`aJ`a%VGd48@iSlK>uYy1p_&TPfp=k7!0*5NT^%UgtMn~?N`!SwK z=yTZu#gU=DB3uv|OGK4z(8h-FX`M(i}J zwOB)&aBm6{kJ2ZfA)znyqg5SrtP8`{yZjz=Rg6Ymnyzy09GV4QIwiZfgKO;W3xacd zypXE7w?sQ9uU6OCfAE1p$#dlat4ESY^2;pagnCoIK-wpUDB6+}q>r_xI`wP;qxSM> zJK@;TX8s--MO;vUtXlYhwny)0MM&(Gmg5TYqSv0OG^8zuKsZliR7V-S(H3SUTihO| znJ*)y(xqwNpTloEqDS1q9FCGjzf5tb^j!Z~B{gxmY$Gyt5?NERnthwm1HXN6z)HTr zX=xC2*W2KSGCHhg$_nuScl1kqF zW0T+)wSL-LT~>jdSJc}^QUx|#ep!$%N3VwjUd~JhLh~D6?L6$$Uu}@m*drz(J~x4U zpg)9>MY}0fQPnZG@Tu?w~` zS92|0HH@j8%#U0dwla#gQZ9RNpfEiJTU9`F3|@V=q^sBKihk1+l~g)^2Mv86m3a3O z>uMqajvywSc&DZ61w#uR>I*YB(%Lr`P;*$<=B7{PAG)_-AvYM>;_ zn((elkJ@G#*WL8EeA%T-gYv!2DLwmMl+k4twd=$H>wC`SP>O4g`UdftQuu;BFBcH% z>!qoKoZZ~Y1jJQthA~Kl02;3rhSk$MKWv6+(W_R>67|I}k9c{R_PV6#TpZM9w+e`> z+knuUXUBs_50=$FQAjWVAb5Sr4iJcZB%8kcC*ZJYkNYWf#tW#!B8z7r>}1(uF&sSDk?a|heXCvajYpx(yD#*m66Z?iTs zd>aYIJ`Uo%f@0^S;}4UsqPOq&Dmnl0a6D|KvSbwBv>`}c7|d>)j!c={SZwQ7t!5(? zAQ(rXvFJ8rw%{o>U8JPyU8I;+OJ!tu?JOlHfjQO`%m;a0i4;?GPxZglK|~Vh(m0sU zE6dmj-%A)6_m~a1z`>z0s4_xTpy zkqTQVEyCJ5BZ9eA-E9kQv5fcsV04v~-L{$I81PjY>+XlYsjjIuKbJB0q(kScNL4k4 z<=_0Ri)>;Yu~Ry@9F&k)c@V$$Eg@*Gi_Fno=+6VYAn|vrnpr)bxKIW`#<;pjBc$+V zkv5c$_n-D;;JjK%^H7Ltfr|QDb(@8Fy99LWgP=xTeRK6jxiBh@lSLyms$^+}HH< zUQAS+f_;n4bL}7e%Nc`EPRYY_ zY(>CMXJw=4O>YZUlZl5@D?jhdv_+ruH!qN5lj>3;zJ19Et_+FWA~8Z-WpQqDeZ@o` z%?n?1+)LRMwlHq@`j&H};d+pDoq}D>C4Yko+iHY; zoqMl#(HKMpXU-PA7h!5JKkmsos6NeNg)woQZTsB3yv~t@!bcQSX5WXR=PJu}S0dNi z6J9O8Mr$dGZ6KrkJv~!Lr(c}f_F&P&ZEzOvS|Y_+NCv^`Av3XuwKHX)1Bt@2#sHHaiaix==-or7 zW?uA9+SaR420l?EIeHsU@b#W;+uHDV9WG5V0asR3d{ypOqU2Y7m=G%yiU)!8H z;AXomja5=Rq*SAGT3}vkXybV$WvN4^Au}thGA|J+;uR}#4Y}<(p86p`LXxvh3ZJLQ zS0hI66)CXEjYX4>IySHv&Ah6iZ|}UTvLvUsaGuZlMpmm(^xU`4GX0Vq@L5?zHji)6 zX#6TA*hgBr(xe%WsP4G!kAL6rvI=>NMO&7L9N!t@lMJ(4_~9OH+kwZuHesvyZ%&y{ z_^D4wdg1W31@FA;>?ju#Y{(;zmv)YDz}`L`;a4}3(e zEXO)v_4rPofh=L^b(lxSZ_GbSr)=85K7KC@CuL1f2YA39y8iLxDAs#%AWu}{$%j~A z&oLvV3xK8-X-AfryXVp21O}soq|u;ksPTf*BVTRoTM)qV!nVJOWH5hUZ6sq_qJs+i za;}6B?1Pz9F@oC~g6=l+F=nFiGj{ndlIfq~Yu=pNPOsM9pj`?4l4kPj8a-4?DpO_#`1Oym0|djO{0p>qnJURC+R1r<0z~NQQN{ zr?Ts@5?RU*CsT_3;26HiL_#78P+UiQdcV){)E_C$~u|HuH=-WzdglTzB<0 zMP9`G`t=>sN$_i`29qjlB<0Lj^R*rmavEFfmQMMRMj_6zRS8EVvM|)c(Z7a6>3T95 z2#Y0mR-$Z#ikKS}`D#=ImZG&|2osvenn;wzG+Wful_R^JdKP)nHv%x6O?TxfdL@8yw3my`5t39NAOR`IAw2uyl6ZAyFd})}fpt zA_Kktnu7=$)Pi8>McIa6W_Em&gl>EG8kJbRni~`LZs_}Yvl8XE&j<14 zD)3*2N{o_QG#^YZ`18dttd#3C$4kZXneg3L7(;1{QG`a^Y9Bhi+a{9kM_c+RKE#%E z`sPgsEPC-J^}!oX>-H$yc}{p)i1dlC{K0l4Uas;0Fr9?~Z|(pPdYAq507SsL9gO?P z(n-Jxc}#j8-_PA+2b5%IzkgT)@b*`L0>NMtPL7K|^8-+>>FRXB9@Q=W2NjR&o+f`P zk^W705Wu!+&EBfuKV#X&6){))G}#uE>?awswYpyPxw$DtoBn$gXnQJuQ0Xr*R>$u@ ztFw`x^=#J8zarbx5J#BO*RiY?oms-usZT?umhW1ms8jfx=NEMnK^G<~Pp&(2JM#nB zwFAkfsyAoQ4EIC;M1;FFd%paeS7S@J5Ir;$^`Zuv?nhr`Xh75Z{SG*1hxA4nPilww z*=pCWBu+d+ak1UQ+}=d7?8Dgk5lY(fMNkk%Iu&TP_Q`f^p5a>!~4a?&jC;c^V-!i-0}ti zG+U*^QEtiIvIS{^TU-kX2Hl`}cZNW2+kK3HB*qBlog!b=Y7Bm)Sq)R~N^cUmFZpJL zf`BisS_Q*V0;u_T0;ppIV-{e1v?oYFa-77{l_SWE|-#a!_q#JpcchZ&kxV7az ziY=O$pTHg9g71_STxfe4E1~JEdnR)qTg|`}C&b0ybo2}WVoQGx)QK+usE^F6L?Dq6 z-~SkAesP%}sC)tYJoX0enP+cO?EMORo?_2G?yU-Yi{@Uauoocx=Z1wboWn^5p6UQG z0QW8zz#m;f!#}$%b&`jQvZvT%URIeliG{H98S_WU?MsX1CHUc3%{0Gr>rzE0M!NpjqjBT(5&~@zg`o*$py( z2*I(Yof@_GToJa<@~kTbNTb8ilR2S0u0gN9rDrYW2Ddn?h`Dn3n-XM+kgCG+7|TPbTn)!bQF1Y zV6MsJ1h|{GS4T?z_#oI`nsOKzW6pejM?@E_TGmQ#tY7FN1Po2Cl_?rnXV|X@1h}O2^baQ%;-rV=0IA@z7Lr0#SUVcsC zV`U*YQ=W=3(@-;dI^ziTDx0xhf86C3^WLNZe|a%~l#F#+K8nEKFPAYU{I_RHT)hCP zT%gzul=##S$}pv^KN})hISCKwzgTc(8wtgRVD_Zkj5X}3(@$!X=imlCpdA#pRQZ2! z6RgQ%6I8Zv5vSCOZdgQF=R-QsMWJHCQT{?QV6ZFKphCIxvyIaFNjeWHMg@vN7d>K- zE2gg+NTER}i!|hE-V?jT&m0FJcV{xN09}i{3YEB(vRq-I;JW9-Ta5Rfl_3!*)F&C)I)H64 zL4HRb-dm7N8zz9wMn6Q<-X~8u8w~&z+DC9J>4jyB#i@_54B{UOfgQqN*7M`*Vk$`l z!Tdi_1{_FRx2!6*D zNu8EZM6O^WqX&M5Hi)>-6TZvrBnsoN3~_uI;8uw9h@3$nCqP*qd`teW?c+YOgx?&tR zf9^f!<7{u(b#{0Q=H@i(q!4B9-_GyD#IiMY(wsTYxwyrZmztV<)(UWHYgB-W)Pe`o zjK>@NQT1PPOz5YV(=f{mItxT&Z+EtJt2V7w8TCFYeZB=wV9VphrJ0`3AG(v2y}Roe$Wxgp*CiEiK_$(g zu9JL` zuUwFVl$rMTziB`6pnOR?yD$5bA z6tN7bYb_g+_Px&OWN`OBPMplT7h|r@=$H&rTXa5_T!i=9-78L;@ZD~vL&7>o>wG06 zqX9!qeAQ9gUg&0vz?~P}1V7enZf3>`=&OX)QctI?#N|#edwkI+KcPm5r zn~BmL(oZ%|kp%x{9Xkd!#6v+e*9{LVhv^clG0;H^ zDVcf~K0b+))+S=)*I1BYoG5E?w3IQ^RbOi^N(;;_m{UaQ4J_Rhbz$;^MT8Q3f^Mu9 zm-kq!2G+i50)z}q1mEGD5F|7TL^-=~@M0W<`ykXlVbnWLJTEucYnb@ZZzfwhw7Gas z(L$1me!E)np-;>Z4EH|XlJ%)p5HZriF3Fu=ISy}H^O-Lsj$oXoG!@HQnOp8MmflOAICraS_ zDY3jnPv}CoE}Jn~oSPzr%n-*M5BkL&Xw8N~gCVx3OP+seZeJvr{&VtZ(b2US;+iqj zvDx}D^ZA~mHv6gg_mfTPVq+&ZmW_<2pxyvtoZVO~>%g z&FJF{(fUjNRmt!kyp`4gUX z$RlWs{>O+aN`jnESjOxx|9K0-I%vRQEWrIZ;x_c$qdP;EXTXL`ohi+2Agn(ON-Bd@bYW(NNtBE7E|Y-7|=;k6Wlgbrm@IU>w(A_!{)PVG$#F%6} zXN+h!x49+hcy6yRFCjLdu8CM|Y@5*4ozf&cANOF#!}2VkE?#`B{Pg+9{R0iFM9*o_-t*%DEG+ggyc%2EOo)xl`0d!nJ2L!h%?s9{f+MFz1Zw^TFzVGB4O)P)9Mi6!wRo1+^(rDtI` z=aIP#KCj$84PGCb4;}5DJne^vmzU+EDd~b`O_#PRKjuHr?Ixth!PG`9&_Mp)K{@0j zLGO&~PnCvA#mdE98n-*N7958Lq!P zOhrqE8{`T)?J?;ak>jt1@f!++od^$z4kq$)UTz>cd^!gjDH*${jpPxm|( zEJTl92u!-nqCd+#HJWvOG5+~K2sU~9oo)}1SzAVefG`3Hw!MLwi4!BM2!}AMC>tmJ zFD`CTdNvjoG5TL(BBJ!H94y>SY^*HoVw_z6i-PNDIjwWmfBmH4$0OWebSDEbq&k-2 zP^xo%+MQ61h&PYKOIKD{AkRtqez%BQm~>%@Fyd|wb+;!6fxs2o?_WNFd~^rW@Nvw@ z+3{IE-f4010?Ef}kMC`-jn2Eckt~_CV^|FvzP+U4k>V*b%Cf#Jg?L&7q^_EBjhtk= zBlm1}F_joyQb#sg%)c*5@^Tg15g+@V<(aeN4c5&g>scDixyOmQ740t#w3*f}tk*4_ zwh^~-Q;dr*A_A*YFIDR3*JiILCQ6JX1}Qp6kBo!)l7f>Bj$k%=QzU3a(PI~20#TT$ zSl1P+h6@y(XAs)_I>(WF)A@X^DsARxmDIxeqa3H_V`t^39WZ*B^OoG1D?HNzol}@Z z8|Z}E(yiJDj}>>7xLqH7xN2C#8XDTht6n~x=0oPUBz8keY`OH)`((>fjYK}dk``0} zP{Jm?m@oxs1L23%3PEIc#tA12b)q-3i;J_=-{|6RlYC<>Vae50Zk$lRYw)L2n11&R z2z#>olYT$v`amzo*1WrFVqu-@0@#DgyGJsfn9ZLnZN=Rxx^R=AGjM8t-!HdE!~!s$ z*=6tdyw(~oz33<>8$Tb)K0RT4|86-bLt=k$HP=)~a)QoV?>5gZFVbg>uT~@Li~*Wd z+3LvEBe3HU9mvqXi{c4l=>oguk*<-A7bhr>dCN9!hVamlK3E{}Q9 zjln=ax!{QTo80&`SGpQoqUApon?R0r%pN=F{(Ahg$0~p+&bTv;ks`Jj<)qMtg zn46KN5+@Y;yYxY5Mopu6``tz4dAwx8d2LCg2kw4s|(OylTrlr2-4=sjuh zXnau$W0**;1kl8nTMc=O-#uwyqB3qOp0!L>!@!Utd*M`i{{g==BiJ0F`v}Lh)Lk`5 zZ|z?${@7YQ!4=PSJ66CZ%e*IrRv2jHhqT0c6$Ho;@QEt6ifSG&E*snSy?fPY&SDQ8 zKC2!ofyq*?j-MaF%aGUw(=`off`06@{97zrwlUsp&73PXIQNEb_ZRnp%Pa zube=GxYQ%<%LDXDkk3c=p|t8D*IO!bx`{7%=AM$bAe%&evFLpm)FV%r6^5v%V4$4B zM)Bhjy-;{D18Dyh&fyyQ!x)DL-fA2QAu`Rw%ftKu2@n>35|ym3jk-xaHp!%@olV1$3R*}g zZ#|*3fka35_{D@5{ia}?_UyQA9uOGQ?Dq*Wi&r!+`HDR~a%o{gZ zvPvY@bn#-C>0t9RJpLB@v79!m7=o+m)3Mh1QaATe`V&<(aZ?_Uxk7__+LNui{$uZ} z$K76x_iaGEQQk6mjjxr}Vw)EK_2=%0PB7Us>Hn{^O@sgSbN5Ck_?$4x(i@ZJMGAH_ z24^OKWts}5_-jNfz(ezs_4}n+GX-sVtaHU8|0ia2G+t5u(KWo#Kv$+}w>%i!6mhXE zY>J#^{NMtqS>>bL7+cYWsx*|~SmO7U@@eDwX%3Xs1L*XZmXSW@WbDeT*KNz~x&2RR-ocYoxNXZ=RY--CoX-FkYuI;sbuk+F$ONn?9Et1h5Y#|(! zlJg6L?YdtCw=zEEN{!ucR~Rr4;iyn*<+j6(osJ09F-C6!p8S{BA51P=sjb9WRq z5zh~?lR9NK!!f>!1{XS8DNp*Jcbz!SwSw7#(f9GGRbh`7U39~E&J(7C?(Vbo#;`UU z7s-+L-kvSp!5xIr`q5%2r0-^;mQl=q^--bmS-($Q6OG9bW4x!TB^&0yq9tgx{|odRdZ1N9eqKq~8``?VX(r znw9%C_zOhy?C^#QDdgC#qE-g_+nkf4@~v!Hb9^Dox0A73MVBKQyz9JcURAJsE-;s6 zE7nNWnx!QAPMWDS51mL9md6UJDZr?rqlL+Ay%^#{u~v|^w4SZXZvEA3tA6_gv^}vb zj;7EfHgm7DEE;IG_6Pz@Dz z)SPRf(6`Eg-|?t~@h&Db`AHz7!(C&foGRT7RcdeBjpgnWBUWGYws&I)CY4asDgI;- z_5|MzgPMr{OQQ}K!y*Q~G!WAF%)bITJ^L(M8eb*@BZX##lA1Io(IJ28nB!Rv@J%N|;&?e@WaVX!{9Y&&$L%pX|v^~HMn4}dK zSk$4ADgl$K#oWkmuZ)}jY3tkAqs?_)mkh7)TUef^nL6Cyg0hgq;Fn|iiyc#u;yyM& zlq|dntSJ@IzZ%b2mhZIq->C9-EKM-5|6Z@25ij;_%8tvHob7+d{&Qb8G?)8u|J*Wj z8O=04lM0xwCTBJrca_8-O4j}`kYiqEbWu14dZ`@@4b?nl_u-xO1#os((#Kj+5^?S9 zhcx5!?F9zZ^%)I7F$H4hjaOt^E!;A zGxpgJVW+l+=LW=z!J{MH8U0oWqQ2|_8hr)Ll25vm=pR4i{L^WO=Y!|6rF6$Gjail! z8Xb#YWtb7zdwMcxxadDzWPuZ*oUL(_?p;}^?N_kcW7HdAceuvv;}2qg06FuVdT3fC z3Sk)vv@(1cxXTo+8FnK09HK-A)?77nQOhI`%sW~^2ZVVIeAMNeYF5kP^s*3u%I={H zWp>6#YdXj5S*Qfc>YiIOQ>Tso5(ANnCe<%p6MH~|NkXYWffhA)CNJ2w=7ex^E0x1PKU7q@uMlG=oFgz5H#8sIT8k zi~vZsCkGZq%>?okjOSr9h%emIbC2Gd*rZ6$)vqF+UnxD=oc`}=rb zQQ}eD=ZcJp#EbUw2CXGb5Y_O{=pml4{cG4)H2=HEA6&DkM66p>ro#2*44<~wH=q}B zLpUlV0Xq~)$%FGh?XJA!{Rx!@(G#WYr>F~zy*WSXy3VH+qhh2hBQ zp2GVUoKPX}ExFQgw;nk=&+Xinw{NO@%pR+IFvbw4UOZtxpTY|y&rlD-WKouH&FZpb z_hKQq@x72G&-Zy6IemzHe7Ve?b*r`~qY0S!Vw9rQ&-_1VrjZv+k(ENo<>00fygh6$ zmT(3kk)D>Lqs%L60(yc^vX%noz@dDpqBJP>*bys*QnP<+mY};!HL7GO&Gh$K0N;OC z2hEz&Ay6O6hse4Ocqee^vv`WxBZ??u8xXNJN5T?)acQZX8>Ce=z$wK zS`zwRSf|=r;@kwb-*k{>{9u-0`!!37=wUyKWEzV`{c6GgZ8^<6=ZJdOQGd>z7FvP zZJ8`*4xP3RstTn}a5cxb+rifVy7{SFtPmhQm@XtIZbpm@YRpxu2xAEWJ0v@UbbA!y z&GpZpVg6$NA+}q_DVD`H``1=U(7XC7R7S6N#@A;Fk*APXEXx%>+4u1|(|bYu+1WSf z|CtM3^E=F0L4kn868-<@f}&zfqU>C(Z1f_`TwL^Q+`qZ#xqtoUrWfJlU}5555#?a! zWdC2ep!&MwMk~rE21f3WP;w!^1w7D%Iu6x~JM-+&fuaBj^AMC!{rJ2hjl~a7T=L_8 z@w6ItOAgu}%nGhtD5^e@z z5=p_-dm2Fy1>Mr0K^}B|k}aBQQcKr(i&9EwYi&YXZAva0ucZ-IpJmEO(YDb}4pbF# z2>dFmY~^kh>vvc>cpCiI?}eI5M-4fyJUwcI3jHPZKka@VYNs`ahDg~ezgJ(#yseD1 zgREyl@@zVlq*%S|(s7(?>F88UaT%>2hB>qdRkYuw*6YIRxE3dyAf(Xt5zacp)|7wlkVV}!XpZn+mgH`bkbAw7Tn1d_%=7E-lIYU7YJY;@j` zgA)~>6nvpdR0vA`C>ma``imoyx%F!0CXwM>XMAgG;IFn?`wzKHRW+ym`#qaIiXm zR#@H@Raz}FsMgOQDM`D&G;As`_w?vCwd+;82y6fAfpkf^nuMQP+;i-@ihks_N^TG2 ze>g7qyKVu#wis&)I%?Zw9cd;S!X)T)7}2F%9Jf~lJtsV{Z#IKdVs)CRG>2pF7ZG95W`)Eq+kAVikyc@pCE6imye0h zLnmuJAwk)&Cyhtauu=hn`lI1G?WupZpCMros7FE<|GZ72FCev^8)A}CdJ&;aA5&A} zljZEJnEkp5npgYbtumumkmu>3v4U}S7=}!4GVxXDodTdEPC~&aM)81{x}@`W%A^Xr z6Wx(n$>f02)}xf<(Uli5(!xATtn>inS2qY8Gd7Tepnd#HoRd|TJsZP?MQ2?dapv(FXn?e_+T28k%IWpA6}Go z-v}UR(}Diver&(vRE|&wjD%526mVzaC@o}cg;mt!h~kf{1X`z-LQMo#A@do48A2OH5=hm{EBU~{$AIkgr<3PQiI1WWx@Ec)+vt?(_De~XZo=KueMrBdC z#wbC!I0xfyF<(MelSaernrFxSLMv_RBksrtRufLZ`iLrGxEo=4B7;>!zzOA<+*5K} zv+6~f_W|4=2X1Y=uK9;IwoZ!H^rOzQnzlQKU)Mh-x?B|yjJ%&tfy`g$_7rNnZ+vh~W!bBsq`o=`xLZ2i80 z3Q5sB#6M`Nv}FEAct!GuqNS(d4zsQ}{npdH{gXrb_PTggJ2p!L+SRGL;AvOo{BRv# zMs$0nSke35aq*lZ<7YF^9Fkqr;pl-7I7T>&Wcs@Kn2VEW;a$Jf^4UaA(%Ti{!Z(5S zk5)R4Kf%pKl~l7ih#pd_N%gVKLkjkd8D8uMeY~A~4f?zo!j?%F9!MWg3+H;mA|p(I zbi5rV()ejGndiQ(SS8ThwETQ2PGLJh9x)KP()GMSTp?s_Mhd^}5XXZK ziiUY1MlQN~iKVz0O|ydtYQf0g8&MN=@x$M3XJ#4$U*;@xZ z!KU8mFnM;$K-^w_KcA_3LHj*zgT=4;6ZLAmTA2=Y86uf)_*a=j;0>`^mMI^~tfBMVfI?7V-CS0)R!2|IqedD&;7y;4@3bWK! zbtGIvP-$ghD~8?}QccP-0lt{%4Vl$oUq^8?dTui7Svd9~mo;sq{@c4NC(Y{+#{Jhj zcWhTXS!T%8O;et%VxvqqoRQQW& zyzR8^XXs{<`5=uLYO=#2IM*SC{ZE>MG)Q8S0xl;x!(DmmSN#1MUk|56J$R(aFvOoh z(Y-^GP+Okx+O%M_>X5&WVjMCLmu6WZmaQY*v9JQBypc8afw>Tv>nL~&CcMiE8lz;~ zE{^{e$99Y_TrSPuXbAC25C-D}NkmI^>^nLws#a_Uly!*U9DdD<2Ipp+gkS(JAR-57%S3=6# zoh$_*r%WMuBPJ<0drJB`N6P*Oz7u=4gkR}vf5q|s4Zzxj3Q%5%JM$xM3jFIRwmoLB z`1fg~Hv!R1apg$1@jkdzQr z1OWk+0|5aWfQAItn8mG10dJsAisHXOs;BTzfj$L9QdC&k4fJvo#!DNp_(6ibUr)N!My>4{R$y{x;^}KuLj&izYdP>Leouv^P2!Vh?AfL1d zS@e_`|AIgk0`aF7vcLQNUv)h?F;@eGkt49yZ|8vD4+IR_m`2Fn6lUlEn%EDdZ`AWY z?1-Y@&ID@IC<+h~koXL2L>yNH(w9zwok#|RKu}!+8wn9hg9fllGf|2IA<%ML;J^-q zQotb0QuJkFfDq)YPN@IJruzXsMc0>x4}=hNxg!Bb0n>m*&e8~A<_7i)oEYK%H?jZc zS&aHwj>&4tI-T9K`Pp_(5aRB){@B4Ni^GYVhHWM zC7(~hW-5fUrGB!MDfD@B)Iu#gnD<(0QPHO5DiC?ciaH9qO9pgh0>TLq)J8kcD zMg)a`6!F`^hgUfY2LY@8v7tvW3V4KUaN-Z-z6Z;6mGq})jO0B5gE-DZJN5Mrs0AWW6%4$g@XCgY%?}J*tNV z{?%z6uro1Uze1-xJ$5?RcHm5Nx*=D7Mi_ra^DHU0C___YoiulM$N{GSQuW}hCSfKX z=v;$KRVD43kWzd-GA8z@C~yW#gZDa&oR|G$1`d-s75Mrvu)~??ZnDp7WfHB^rf%RtN84N9Ei5LfEYQSm84v6~$$4 z!c_76+dE6~PkYdShF-Xp?ZNBQ^2DjyVs4kUB1PV>n6K`r(>Ibo%+~(a^_$Cu&WpoE zp09sD-F_sZw}bR)oM2oW-?=ipl|>Qy_AErT)#TRb*IPqKjjN6Xx#p7SOl~LSB(EFa zD;CoW0Y?CdOt~a=ZSqndlNy%TOsZ(`K7}k{q#6BA#BbSj(OPxgjn&S0(?r2HDG0Uak+;j`vaJ}Aiyd4yb z???JRh?BT#m=?I}*#1um?~h}_!!GC@5r*DV2@&0ZJ{`ZSW~A|v z5Gcnv2@Q>OZMVMI!m=`jZjXQA^==MES=Wnd-->c?YvGOy3b_epIqs@gUDw^MkSj}T zv_I9VBIZx5#AEPj=;?vq;?ANBM-%X>Qp#X6+I7FCRI1nI+u>A{mlxL8E2c2$tUYUb z=hZBq^6>JC9hVrqUi%7?)pXvKH-Ihh*) zqmcK$)2+Vf3zL5*N=$92yq@Ig+IVv0D{JguEd6Mw6Dy`t=@|?GDGjA>d%3k0kMk-c zx6iL<-xIh=Hbs|BKAL&-+QoLq;D4*KI&amhYFlqJjcS$@iFAOyat2mzco2U~YWRhC^nS^W3s=$7S(& zwr`tG4AS)H?(_19EaxV2$>%~zOw>M=YzDS3A+M>7*VhnUb!-P}b@!W;`?SmYBYmg< z*Tanb2!TO&&&Q$49PehXal<5smQ{xT#~;ll+J38CI3j~hC*p?PCU-g^`y&Sj$WC+q zLq*a>MFFoVKeHm%v~HX0*}YUf_d|mF`KDgZEjN+o)uT-Z*_-K>ElSU;wvvU##X$=s zplt8{Fgv`5yE7~9tLeObkZzVuPxN*pez-6%m&*UVBGT=Af%Se=LGq^e{i)~J7mPJ} z?fd-ReVh9-K;k$**)nok;@e=SeHM7_`|VjjN|`wl5lBA% zBKiDD37!P#bi<%gk~iSqJlBs6c40~5++?K*3&7UKvJzD!6quaB^l4x+ti)IBz8>qv zsTkxQ8iW#1A_+XyHn!BfwjPm$;?pfIF5cBp^{WK_%M*UN+5TpLB5=;@d|R_}5X>i( znG;@?14OetO1zN8^3jf`&__;FeOGmCD-M_7rOIrhF&Gu;LMxljBF5135rJ*_w$YCy zi24+KMGJ>X7bi~SNe5YMt9w2Tj>4x~!~v)QyhsSMzW=%Ur;M}5q zd<5JL*2*g#|Lq^M*FR0N%i`F%;W@v+ar{D>N>q~L=Kh$aPF`&|9#N9#CvXA3z+Rs< z`Fv`bPMVi{57BmbHF3zQF4BGeu1+<}^D zohA%Oxz8KDd3~rqObx1dfu9o}iu|GnCJE5SKY={^=g`Z-?%!1(=i& z$5jEzb`|zKnV--skSU3MV`5_qk!GK~fLU$_p?Rb^I7;zBisgdw7dnwk_y zdfeDKPTKj>mw0^|>K1)9zoU1HHEMgxp zakT83R63z=MRw;LM{DJ=z2d#jGfT!>re0h+k4zjZ;1EV-IkQn~{CG7V${xC&r#CG~WV zHYT3YvpXw!&dYLMdiu;GYv#UxU>)`bBF0$x=OU_k$rHr9-=+SmV)j{oE)pz36y&<@ zZ0)&^vZrbF7VP%zbl&VHdN1{Qe5o0kmlveB>v~MVci!>8rSMpfp>JLx-H0va#GX!P zCfmZkYRG->ylD9b-TnH-ImRh3DC_)f$#T)WUcI}7BYUfgU(=b@tvA}Z>ZP~X-j<}? znLR0;*6au5{9v@IOOcwSimH!(jck|kkJ9s9LN(-tnZ22I%}0a+W%H-NXQ;BB%3^=! zdg~{uj@~VH9q_sv^&MT(vRiaj;_$vSN!4KpCAux^t{MOLBQ{a^*|+|LWd?H5 zXms7g4S;Ny!P2%@_{iCaXSMJx=y_I_u)42SRBSR;8~QyRiFNc}CY)+Ay7?8q5xJUsd}N#5(6r3>fe(yD8Dw}|c| z2f0bN?48=4p39@GtSn`wcI}_qv+=szTIM~lo0}BtbwG9-FzQkCb`UUz+uhEn)brq% zxYbGj_*Qw|fgx_0xyom2gV?A2Ww@fOH=k;)JKgxo*efvgQ8Vk8Qd@XtN5VCoqEe+L zbr|NlwL`a_evZ4#v2IP48bWr?x#{K9S<-e@@FCiI92c@E@8jXn+%Un_wKXsCTyo|! z-;c=4Ca~rE{b{^60CTr)RUKY4|K7Om{mkz;fD$^KYX{TPKO4Lk3&P`eyKm1^LpeDG#Hc^_JkNUjZNyELh9IFOE+m^ zGe4kLb~2k+E#~_S#_^0(4#vP;LOXH(#^Wg6?63q&57jQ2dFQvHXH{Xgn%<`k$iDO^8b~i_B6-e6CGNQD1sARk#~X zYkg-T3`gTttd4(2_(F8^3Z-d>vWX+NJLSegr;~Qc^hQ=$PA8}7AiId-t1oRQ@{YZy zvbdd$bl1L@ACkrc)Or~C`|S{+4k9?&-jP&SlpO6#YtNUjix|t?l*Wd#XyJ4P^i&yq z?RxZvgYYme_yUboJ7)ia`A19K58lSC;ZQK z-!-OV&R_(WX#Gd8hjZPQIZ3hnlK-kMa3X|&K_`H;#HFtBOrb38g~lSwJ8#1Ki^W1u zfdA2g@L4IZqe2tcjF8GHr;XM+NAKsM(G=|8QM38?QMH>y2j#9E=`?RBDOyvh!vT@P zibMVM=Q(agjV6h5Ji?T-cJV^PmkVT&uH5%2pQ&!WzXq#ool0C?R*bU+#}q2Q$q|z8 z!A=}luUA}Mo}nOpuZRhxI4J+>8jmo`D!WD6*Ig5fWQpP_8WHCqeTo zB$$@ACv%X~2!1{q((o&?Tv*T`5z&^Wy?i34!7YFP$^ig_Z9Bb$@G9V zHQX)^1N>Z3uAP~D3~fqMb)12TK~;TYQ*Nouk&fTagYK^NJC>XdEe(>|<18a21hT}> zURp6t%-^Iy$toQfrzbf00)c_N5QCU&zMcv7KcNgr{!N>AasE@o{)^cu!SVm8V5UG} ztN~&AKdH+Ch-;*a0ty)rEWqVSw{e36;v|66D>gA8|4&%c00t%Ne%AkRnm`;q92rn{ z^Pd1x1XH{mVIXb}sFqo1U<0)bXk(!6!Mc6}{~u1(Z%1bQpTvJdHvorT4Ke#qZEFPL z{@*y|vH2JiV_mqUHQ&|IKhDCOn9B{okya0IN~KbS_u6n zqA!7^T8IVxM1%2U;-d*ilp2`7l1O}k`{JWYR=XaBtlVTH?N(7!leRs)r00)xzh=1Y z9`g$_HH>gMz!rOx_z(kwh4LeQp(;Ww8qR3a`(aLv5qgTR+RR4%eMXOzU~PTfWOnbz z-0W)nu=GT}O_bl4u(gE-NmUg+OSwzqLa6L>Mn=3M$}i`uk2Vs%Rp)K&!lYSv@bPDaIcL=#?+Z`j z$*hWsJ&e7wze+OQ-r!2^XA&##EwFJAJ>Zc_R8EP)l7Fg=MWh_wLfm+14#|uwYVp$M zOy)s3%poxEoDGiz1mFLBm!vi?? zENFJ~;t-`9xMFJ>3!jyXhH68~^(J@uddJ43aM;^9gWl(Bm=X3x14(eC`b**|gY{M- z>=7-hAun?wkM599;4r6Rp*nDX%^X-F(5sE7TL`>CN%qh|ZR!;G>O0RUrC{Fy70iiP zo`Is$N_0sSS5C4x6yqN5V3s}e+9o=B0}^EG>M^`)aD3eAR<1{wPiU(fH3L5J^DPA@8dY)wl{(Z zep`B53CIv0JW6NBxl}S~-cS5)%t0_3l5&3mFYsPC)STN` zQ42I~NAR{oFwnuGobxjsK>~Vx!87F4eCJ2a@gXl-iREIBbT*T!Ejn#B->O{J&zXe< z>O-UPeagQ+w34B(a7Tl(00elQ#6{s{H=sbdZ`yp-Ki^azf^3RgU1kGt1%wLa5a<oGNt@`s@xe-*HJo4VpE(Cgh_Qnak;TDrUFZS9>Tn6C13d`PwLY^h*^%_jAIn{&xk`>4P%U zr}}xj2mksrOAUtO^lD$M-R-i{^hn}f9d0EJIw?i=>Hk?# zNMSwJ+}u3aB)B>F*T00MqQ7=*m$~qFP@Z(i)XnKn1Zj;fB8~UNk3Naw*=yP8NY*7o zw-to^zN`<0Sslbl>CAtcR@VZS2#N^S*)2AexCIAoGTTbqNIZHrkp|{J zST56W){1E7mH_ukp*dInpN8gtEZt58nj&f`*LamaeJ8s+x8heniDDzk;o9Dcx&+T^ z97EiDjNTHk8{0!Vse_6kMG!^ zF<-Ob&>m8hnW>`Ebw7LT{B7t7ouA`#QL^9yxYz9ObhzEaR&PJeYH!YHml-wM6kH?t zN?VA*Cs;0Sify;3Cds!s&-JU)AR zu3T3jI!v;6O1vwiI#w4!W-}z(ik%$KBsOblzWZiq_@)M*Ui?^5Zs8ShC&BvX!jJcBnt7W9o;(}RO#Y|z+1FbA(gt5>a@b6+W4h>ABzwo>Efssc zbHu@$Xz$Mj$u0>oIxG5i-mbek&O%RVt6;6v2wg<)@~gWNG^MuoPauosG1XrWcHjEe zXfPeGTASc}iIf zsdDy*uz23#^eB->ha>j!{?#Lh7ckSiKz2Nu2UYlgwRi5}P=0G4cPb=NiEBjbSj%yvzH0_xszs zYwzoN-#_*r`?}2hHP`dp_w_vMS+mw>-S@q|Pxa-x(4!5-90K&NDYb@g1YhFUjN~_r z3(HlUc<3kU0bhD|sAkwMvlej{*Me7efywC5t8O&MH^gBY<9iWap@+Em$7m?4ms@ZI!^c37lM(;)ibtE6w>nu&-Ujz&Cezikn`P@ z@~^Rl)7`#B$4n9am>jkNvBe1tb0n;tuX)!lE0@d0sp0}hkDe7ecX`itV}(2r5GYd@ z6ajc022#S3#~(SI0(7kbO!6A5ssS1+f;3;4jY`6HUIB&~=*`*QZw`V;nh@YO#j|%Y zCwXp`trJIBSfsdhij5Rb}vFb2OU0WhA1gJc2VB%zR9=W zc*_}&w#iL6nmQ}H)i-&As~zS!WdF8pLT@~ktg10|M7ZSgfu-fWdRMSmBs=BQCi)+I z)9V*e+o2()Qk4Eun3n5mY&_GOrI*;DSn>+4egX=TodnUYi?;@q%KV;>_b*7%f?^?& zR?f_qUSHT=aO)lmTJ~3+L9jr20`VI~Mq>K3;!5-E#Kfbw74>8Gp?S+4d>Qf%JEr3s z9w0!Aa5|N=?#k{nYr44vREz1ku_6k|$g;0W8SJIH`7p=hh$4-|q zI#*pQ(jVQ%l!ql*JeHlNl@C*Y2EKc&X%@4InPRiE&N`BHhjsz$J|4~5&G<9)#yk-1 zncs>$s3$Mp)?6Swpjub(z}qTjMu)MOdZar)knzHDV0sU#qZ39d^xk5NPIwZ$Z3uHA zNXiUxE35CDxMvg+=6$v}V)a(P|psSG_+lAXOHEoGpW6aRO_W8ruSEgnrCMJ`2 zdLcxjQ1dzdV#4*lNQt`GolgVNYN&Zf*=b}h%Oo!kdk3qmE1lYBE(mAY-LK9I*86BU zbN)IM{WT&hX)vhMk>#cu%1LwlT(-BDQqCH9)S!cJ)dL-pt{!_SkZET!KivAT4{Qc0 z4Y!rEdO&OTU)$6P4X>7H3+c2L7?V6{KCy+vBl#PkX1@Jr^B)K8ct_Mdav%n)dA(Uh z;3cv8cAAYqHN3Yb;Z|=FHT$j3q-S5XT$pW%tG;l{$!9zj6VMdmSRiq$kb<*X<<-b! z-2;jtAv-}f{j}oPW!s1W;yWZXA;j;qO7iwWIWY$kK_WFLIV+Wtm(d`OHlO0Oyr!*!rm0k2Q zES_kt)Pgvs(4bj}Zj0k-ZHR#QK538~b~m#$1>|NA*dcfC6EQv^iD*#Ib2vTYIfzZJ zgPVQqCqaTm2BdwFAIXxo6wzoH4#l8AL?Qkj+46P8fQ(HS=cWxW&lL16D5t;kUBiW4stIp6kMsn&b!*9Fr*Rul!83xgwXaOID#9r3&B#9nb7XJkdJj28O|qB5F~B&lD0 zaK)zPK!#;-{oyPRCQZRk=3Xm=_sEy|Oi7u7y-rK3ZkQrez{6G|=PQ-Qos6Y4A|RyW zS{40L+Jqk-L!ECnAGv(;9G>{))j7tOoz@9%|9770_H~%2|;e+z|w>k(;8cY?NZ)XScj^+9~etPPGpdzYCxo2s@M# zJQIarjUZ4ljp8lo+5BD<@zi<%-V~fvb6Tw)>G$CV&Now+U$c$LBR-Thi>=hD44lk~ z>AncAyjt*BI(ZPQmaNp20F~;=q4n&PW|Fz9jnr@MHYE0^x9J7x=UNQsx9Tgr%dW~| z$5|VVoqV#q_=7P)cT|p!w)7tCi>URFm70JkpyJjlD2|%Y^40vwf{_#kf}(Gbv!E46 z=k|Sf&3|LDrZXDME5-mdub(CuKw1vHwQ7#aDz~SyllL$N_D+GiF+nPL91gc$QDel(VXOG<0VBLpYsKuX$^534>-cDuqsqVJVJj5=Bdc3w*eTVowoa9OT!>wBqf`b(9?Naw{#{d{%Jkr>$Y zZi+eQ{la3!2VKnCa+nlaVl6Zkn_F6#OUF@%x~K(n*~DdRAeS8w1%3TWTE6RWQG9*1 zbaw8U@mVsAs}AAJ3SuH=O_g+yvRzV1hP$_%a9)EIZh04`YOC&+N@j)1>vyfW zpZ+*n+*wbeF8J%uPx=ggbEA+6i@iv#)%NA#=uoIv|FN-|8#%*-V%&uO2H9(#gE1#GSc13@k zbfV8TX6Mxsk`SdopS5`gbVIT_Ch`fYIqg~^SW;#R=fE<+w;Q$*B7{;}}-4-4g zg8%T4qNPauEEz%H*#@ODy&W}H+61{s)$r$2^~AY(tcTfj1)VwXX>)6TlS(1=^o zS{G^^JXI1gSx!S=;tu1Vzyf+p-(H+)eSL{sWu69ISXfBIwbpmM_MLZvOeA`fHuqGl z%+etb`4{O30i0!b=Br~g>8?n!=9Pr7D9NxP6l}0dk1mDAAIeRJ_|#y8nkg2KT2X)h~sSiJ!i zWpM0yM{m*m9(qOg=rJXf`De?yT^i?^3s><%CC?Frvs<_K)Mq7C2hARj2%afN$nK{f zC*s@h_n#RiC956yeHrEs|A8_r)FSZa*=#_S1S7lzgV5mJ~6|eA>xmN>k9H{ zXcBx{#}Z9xW|V=_1gTyRxKJ@=#JHMcRpRQs_E7Bz`NRe92aS?)Ja{ z(GrXvC~*?#PjCE#PiPC%<+jAj26i3_^+|YhA}4J+Hr(0A$H%ebLcj&4?{3jkJtM`_ zshRDa5q4o<&rZMe+41?HSJ5fb?{3WXFQgpIou~1i5UI{WjD`Q^P?g0o^5TN9Vv$&3r>7s`%Y(aj6*!dq^fFi-D`e(`^m2H61P7GLO0|=|+!w=?%MA`3)%7xrCT#bv!Ky|aZi_S}q zD^ph}E_?Zw)hnglsORh2y_=uF^m@M^$Kkdc*+8@^59QB{(C9Z@jNx!+?%Lpp{i-I~ z=7zCOf31+KBCwHkuqeIGhbz~$W12^>%G^rh!)H5@sJ)>?G#aX!Lw*qqY8tVqSW6uL zGjf2rk#a5tM$>?dEu8c#L*FF$7U$b}ENPY#t&F57kE|1-W`tY;QR*}t>^yE{WCCwg~n|tPUp=|KFY!yjp>oXqg)6hFjIW*{lZnRPf>Xi0EDYy^pr6Y&$-KCXu zHv9CbC3bfy1vZbDSrP|fe4(J}M^YKu^9#bv5&u13z9-`p)q}kd)Qr-T ztwHZEfm&N)aC_8#9R+95@R?!S90NXiG2uWmo0Z8y}QZxMFScg_o)%eS&~wFWCn!=ycH^U{qza>sJU6|U>msIDMSL) zi4%hi-HLB`%+EI?;T%1mta@(`A1|D1YaLJjdQ43Ikb<*HrID4!mG7VqLJ!2Ol59V3 z7Z85~9@^^{SHS9`8}vF)v(u*H#+4u_{4O>_PC(oXtSw6StH=Qpung%iOY{dv!P;aj zBi>hlS0D#O%QhTtwBbg#+4!ey3=SLP;l`Y@F^z7J!v-w<`}pv_3N#l818iT{0{A=l zvy=Up9|DV{^#=#Z*=+9^jCH2b(=p; zFM*fB{6Dp-e|7$=+}U5wJ@)*~`Ttq`>{sW%YO?(0Tt)Hk6k2{Y`&AC)FS9-+9-jXd n2l<=Xzmk7gH~aImPvxJBLD-mYT33AF*$lqvph>GS>%aaB=w8H! From fa07747982ba21548b8e08d809595e66f83bb1eb Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Tue, 25 May 2021 17:54:13 -0600 Subject: [PATCH 135/404] Refactored out the reduntant pbProject global variable in the generation configuration --- .../bloc_generation_configuration.dart | 4 ++-- .../pb_generation_configuration.dart | 21 ++++++++----------- .../provider_generation_configuration.dart | 2 +- .../riverpod_generation_configuration.dart | 2 +- .../stateful_generation_configuration.dart | 4 ++-- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart index fef20b43..91d823dd 100644 --- a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart @@ -7,7 +7,7 @@ class BLoCGenerationConfiguration extends GenerationConfiguration { BLoCGenerationConfiguration(); @override - Future setUpConfiguration() async { + Future setUpConfiguration(pbProject) async { logger = Logger('BLoC'); logger.info( 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); @@ -16,6 +16,6 @@ class BLoCGenerationConfiguration extends GenerationConfiguration { registerMiddleware(BLoCMiddleware(generationManager)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); - return super.setUpConfiguration(); + return super.setUpConfiguration(pbProject); } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 777d7757..103dca4f 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -37,9 +37,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { final Set _middleware = {}; Set get middlewares => _middleware; - ///The project that contains the node for all the pages. - PBProject pbProject; - ///The manager in charge of the independent [PBGenerator]s by providing an interface for adding imports, global variables, etc. /// ///The default [PBGenerationManager] will be [PBFlutterGenerator] @@ -110,14 +107,13 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { return node; } - ///generates the Project based on the [pb_project] + ///Generates the [PBIntermediateTree]s within the [pb_project] Future generateProject(PBProject pb_project) async { - pbProject = pb_project; var poLinker = PBPlatformOrientationLinkerService(); - await setUpConfiguration(); - pbProject.fileStructureStrategy = fileStructureStrategy; - var trees = IntermediateTopoIterator(pbProject.forest); + await setUpConfiguration(pb_project); + pb_project.fileStructureStrategy = fileStructureStrategy; + var trees = IntermediateTopoIterator(pb_project.forest); while (trees.moveNext()) { var tree = trees.current; @@ -154,7 +150,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { if (_importProcessor.imports.isNotEmpty) { var treePath = p.join( - pbProject.projectAbsPath, command.WIDGET_PATH, '$fileName.dart'); + pb_project.projectAbsPath, command.WIDGET_PATH, '$fileName.dart'); _traverseTreeForImports(tree, treePath); } } else if (tree.rootNode is InheritedScaffold) { @@ -166,7 +162,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ); if (_importProcessor.imports.isNotEmpty) { - var treePath = p.join(pbProject.projectAbsPath, + var treePath = p.join(pb_project.projectAbsPath, WriteScreenCommand.SCREEN_PATH, '$fileName.dart'); _traverseTreeForImports(tree, treePath); } @@ -179,7 +175,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ); if (_importProcessor.imports.isNotEmpty) { - var treePath = p.join(pbProject.projectAbsPath, command.SYMBOL_PATH, + var treePath = p.join(pb_project.projectAbsPath, command.SYMBOL_PATH, command.relativePath, '$fileName.dart'); _traverseTreeForImports(tree, treePath); } @@ -215,7 +211,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } } - Future setUpConfiguration() async { + ///Configure the required classes for the [PBGenerationConfiguration] + Future setUpConfiguration(PBProject pbProject) async { fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject); commandObservers.add(fileStructureStrategy); diff --git a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart index a0fded5b..96d576b1 100644 --- a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart @@ -14,7 +14,7 @@ class ProviderGenerationConfiguration extends GenerationConfiguration { Set registeredModels = {}; @override - Future setUpConfiguration() async { + Future setUpConfiguration(pbProject) async { logger = Logger('Provider'); logger.info( 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); diff --git a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart index 767b95fd..52a58c0b 100644 --- a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart @@ -9,7 +9,7 @@ class RiverpodGenerationConfiguration extends GenerationConfiguration { RiverpodGenerationConfiguration(); @override - Future setUpConfiguration() async { + Future setUpConfiguration(pbProject) async { logger = Logger('Riverpod'); logger.info( 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); diff --git a/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart index ea22f7c0..3dfbaffa 100644 --- a/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart @@ -6,12 +6,12 @@ class StatefulGenerationConfiguration extends GenerationConfiguration { StatefulGenerationConfiguration(); @override - Future setUpConfiguration() async { + Future setUpConfiguration(pbProject) async { fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject); registerMiddleware(StatefulMiddleware(generationManager)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); - return super.setUpConfiguration(); + return super.setUpConfiguration(pbProject); } } From 4cdfa864c37e600f93e6c6c52e8bf8727bfe63c3 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Tue, 25 May 2021 20:05:06 -0600 Subject: [PATCH 136/404] Added a interface that allows the traversal of the nodes within a [PBIntermediateTree] without having to delegate that responsability to the caller, the tree leverages the Iterator methods from dart to traverse or transform the data. Finally, added a unit test to confirm the traversal of the [PBIntermediateTree] are working properly. --- .../generators/util/topo_tree_iterator.dart | 2 +- .../pb_generation_configuration.dart | 5 ++- .../subclasses/pb_intermediate_node.dart | 6 ++- .../pb_layout_intermediate_node.dart | 1 + .../helpers/pb_intermediate_dfs_iterator.dart | 32 ++++++++++++++ .../helpers/pb_intermediate_node_tree.dart | 16 ++++++- .../dfs_iterator_test.dart | 43 +++++++++++++++++++ 7 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart create mode 100644 test/lib/interpret_and_optimize/dfs_iterator_test.dart diff --git a/lib/generation/generators/util/topo_tree_iterator.dart b/lib/generation/generators/util/topo_tree_iterator.dart index 997a736a..a84ff44c 100644 --- a/lib/generation/generators/util/topo_tree_iterator.dart +++ b/lib/generation/generators/util/topo_tree_iterator.dart @@ -27,8 +27,8 @@ class IntermediateTopoIterator IntermediateTopoIterator(this.trees) { trees = topologicalSort(trees); if (trees.isNotEmpty) { - _currentElement = trees[0]; trees = List.from(trees.reversed); + _currentElement = trees[0]; } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 103dca4f..8aa460c6 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -87,7 +87,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { return symbolMaster?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false; } - Future _iterateNode(PBIntermediateNode node) async { + Future _applyMiddlewareToNode( + PBIntermediateNode node) async { var stack = [node]; while (stack.isNotEmpty) { var currentNode = stack.removeLast(); @@ -135,7 +136,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { (tree.rootNode as InheritedScaffold).isHomeScreen) { await _setMainScreen(tree, '$relPath.dart'); } - await _iterateNode(tree.rootNode); + await _applyMiddlewareToNode(tree.rootNode); var command; if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 455a8216..813b3941 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:quick_log/quick_log.dart'; @@ -11,7 +12,7 @@ import 'package:quick_log/quick_log.dart'; /// PB’s representation of the intermediate representation for a sketch node. /// Usually, we work with its subclasses. We normalize several aspects of data that a sketch node presents in order to work better at the intermediate level. /// Sometimes, PBNode’s do not have a direct representation of a sketch node. For example, most layout nodes are primarily made through and understanding of a need for a layout. -abstract class PBIntermediateNode { +abstract class PBIntermediateNode extends TraversableNode { static final logger = Logger('PBIntermediateNode'); /// A subsemantic is contextual info to be analyzed in or in-between the visual generation & layout generation services. @@ -29,6 +30,9 @@ abstract class PBIntermediateNode { List get attributes => _attributes; + @override + List get children => [child]; + /// Gets the [PBIntermediateNode] at attribute `child` PBIntermediateNode get child => getAttributeNamed('child')?.attributeNode; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index de4851ce..66601d1d 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -15,6 +15,7 @@ import 'package:uuid/uuid.dart'; abstract class PBLayoutIntermediateNode extends PBIntermediateNode implements PBInjectedIntermediate, PrototypeEnable { ///Getting the children + @override List get children => getAttributeNamed('children')?.attributeNodes; diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart new file mode 100644 index 00000000..f4777a12 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart @@ -0,0 +1,32 @@ +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + +/// Iterating the Intermediate Tree by DFS +class IntermediateDFSIterator + implements Iterator { + final PBIntermediateTree _tree; + + E _currentElement; + E get currentElement => _currentElement; + + List _stack; + + IntermediateDFSIterator(this._tree, {E startingNode}) { + var initNode = startingNode ?? _tree.rootNode; + if (initNode == null) { + throw NullThrownError(); + } + _stack = [initNode]; + } + @override + bool moveNext() { + if (_stack.isNotEmpty) { + _currentElement = _stack.removeAt(0); + _stack.addAll((_currentElement.children ?? []).cast()); + return true; + } + return false; + } + + @override + E get current => _currentElement; +} diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 7a31f06f..e8ad4105 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; import 'package:uuid/uuid.dart'; enum TREE_TYPE { @@ -8,7 +9,7 @@ enum TREE_TYPE { VIEW, } -class PBIntermediateTree { +class PBIntermediateTree extends Iterable { String _UUID; String get UUID => _UUID; @@ -47,4 +48,17 @@ class PBIntermediateTree { _dependentsOn.add(dependent); } } + + @override + Iterator get iterator => IntermediateDFSIterator(this); +} + +/// By extending the class, any node could be used in any iterator to traverse its +/// internals. +/// +/// In the example of the [PBIntermediateNode], you can traverse the [PBIntermediateNode]s +/// children by using the [IntermediateDFSIterator]. Furthermore, this allows the +/// [PBIntermediateTree] to traverse through its nodes, leveraging the dart methods. +abstract class TraversableNode { + List children; } diff --git a/test/lib/interpret_and_optimize/dfs_iterator_test.dart b/test/lib/interpret_and_optimize/dfs_iterator_test.dart new file mode 100644 index 00000000..78c3e4fa --- /dev/null +++ b/test/lib/interpret_and_optimize/dfs_iterator_test.dart @@ -0,0 +1,43 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:test/test.dart'; +import 'package:mockito/mockito.dart'; + +class MockContainer extends Mock implements PBIntermediateNode {} + +void main() { + var containerList; + var numberOfContainers; + var rootNode; + PBIntermediateTree tree; + group('Testing the PBIntermediateTree', () { + setUp(() { + numberOfContainers = 10; + containerList = List.generate((numberOfContainers ~/ 2), (idx) { + var container = MockContainer(); + + var containerChild = MockContainer(); + when(containerChild.UUID).thenReturn(('C_$idx')); + + when(container.children).thenReturn([containerChild]); + when(container.UUID).thenReturn('P_$idx'); + return container; + }); + + rootNode = MockContainer(); + when(rootNode.UUID).thenReturn('R_123'); + when(rootNode.children).thenReturn(containerList); + + tree = PBIntermediateTree('Example'); + tree.rootNode = rootNode; + + ///Taking into account the [rootNode] + numberOfContainers++; + }); + + test('Testing the traversal of the IntermediateTree', () { + expect(tree.length, numberOfContainers); + expect(tree.first, rootNode); + }); + }); +} From 57691fc6f621632e02dcfb7433c7d53d29f42c5c Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Tue, 25 May 2021 23:11:51 -0600 Subject: [PATCH 137/404] Added the ability for the FileStructureStrategy to run in a dry run manner. When creating a file, the file structure is not actually going to create the file, but record it that it ran in dry run mode. The primary purpose for this is just to notify the listener of the final path of the files before actually commit them into the files sytem. --- .../pb_file_structure_strategy.dart | 96 ++++++++++++++----- .../pb_generation_configuration.dart | 44 +++------ .../helpers/pb_intermediate_dfs_iterator.dart | 2 +- 3 files changed, 88 insertions(+), 54 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index b05f4bd4..bdba803f 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -12,29 +12,38 @@ import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart' import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:tuple/tuple.dart'; ///Responsible for creating a particular file structure depending in the structure /// ///For example, in the provider strategy, there would be a directory for the models and the providers, -///while something like BLoC will assign a directory to a single +///while something like BLoC will assign a directory to a single. +/// +/// The [FileStructureStrategy] can also perform a dry run of the all the [writeDataToFile] calls +/// that are going to be performed. This is useful for notifying the [FileWriterObserver]s of new files that +/// are being written into the file system without actually writing them into the system. The main purpose +/// of this functionality is mimicking the file creation to observers like the [ImportHelper] can record all of the imports. abstract class FileStructureStrategy implements CommandInvoker { - ///The path of where all the views are going to be generated. + final Logger logger = Logger('FileStructureStrategy'); + + ///The `default` path of where all the views are going to be generated. /// ///The views is anything that is not a screen, for example, symbol masters ///are going to be generated in this folder if not specified otherwise. final RELATIVE_VIEW_PATH = 'lib/widgets/'; - ///The path of where all the screens are going to be generated. + ///The `default` path of where all the screens are going to be generated. final RELATIVE_SCREEN_PATH = 'lib/screens/'; - Logger logger; - ///Path of where the project is generated final String GENERATED_PROJECT_PATH; + @Deprecated( + 'Each of the methods should be receiving its own [PBProject] instance.') final PBProject _pbProject; - ///The page writer used to generated the actual files. + @Deprecated( + 'We are now using the [FileStructureCommands] instead of the page Writter') final PBPageWriter _pageWriter; PBPageWriter get pageWriter => _pageWriter; @@ -50,12 +59,33 @@ abstract class FileStructureStrategy implements CommandInvoker { ///Before generating any files, the caller must call the [setUpDirectories] bool isSetUp = false; + /// The flag indicates when the [writeDataToFile] is going to mimic the creation + /// of the files. + /// + /// If [_inDryRunMode] is `true`, then any file creation is going to be simulated and remain on + /// hold on the [_dryRunMethodCalls] list. If you are running the [FileStructureStrategy] [_inDryRunMode], then + /// make sure to run [writeDryRunCommands] at the end to execute all the recored [writeDataToFile] calls. + bool _inDryRunMode = false; + set inDryRunMode(bool dryRun) => _inDryRunMode = dryRun; + + /// The flag, if `true`, notifies all the [FileWriterObserver]s twice when a file is created (assuming that its running in [_inDryRunMode]). + /// + /// If you want to only notify the [FileWriterObserver]s when the actual file is created, then + /// [_dryRunModeNotify] flag should be `false` + bool _dryRunModeNotify; + set dryRunModeNotify(bool notify) => _dryRunModeNotify = notify; + + List _dryRunMethodCalls; + String _screenDirectoryPath; String _viewDirectoryPath; FileStructureStrategy( - this.GENERATED_PROJECT_PATH, this._pageWriter, this._pbProject) { - logger = Logger(runtimeType.toString()); + this.GENERATED_PROJECT_PATH, + this._pageWriter, + this._pbProject, + ) { + _dryRunMethodCalls = []; } void addFileObserver(FileWriterObserver observer) { @@ -70,8 +100,9 @@ abstract class FileStructureStrategy implements CommandInvoker { ///[RELATIVE_VIEW_PATH] and [RELATIVE_SCREEN_PATH]. Future setUpDirectories() async { if (!isSetUp) { - _screenDirectoryPath = '$GENERATED_PROJECT_PATH$RELATIVE_SCREEN_PATH'; - _viewDirectoryPath = '$GENERATED_PROJECT_PATH$RELATIVE_VIEW_PATH'; + _screenDirectoryPath = + p.join(GENERATED_PROJECT_PATH, RELATIVE_SCREEN_PATH); + _viewDirectoryPath = p.join(GENERATED_PROJECT_PATH, RELATIVE_VIEW_PATH); _pbProject.forest.forEach((dir) { if (dir.rootNode != null) { addImportsInfo(dir); @@ -92,12 +123,13 @@ abstract class FileStructureStrategy implements CommandInvoker { if (name != null) { var uuid = node is PBSharedMasterNode ? node.SYMBOL_ID : node.UUID; var path = node is PBSharedMasterNode - ? '$_viewDirectoryPath${tree.name.snakeCase}/$name.dart' // Removed .g - : '$_screenDirectoryPath${tree.name.snakeCase}/$name.dart'; + ? p.join(_viewDirectoryPath, tree.name.snakeCase, name) + : p.join(_screenDirectoryPath, tree.name.snakeCase, name); if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { - path = - '$_screenDirectoryPath$name/${poLinker.stripPlatform(tree.rootNode.managerData.platform)}/$name.dart'; + path = p.join(_screenDirectoryPath, name, + poLinker.stripPlatform(tree.rootNode.managerData.platform), name); } + path = p.setExtension(path, '.dart'); PBGenCache().setPathToCache(uuid, path); } else { logger.warning( @@ -112,20 +144,31 @@ abstract class FileStructureStrategy implements CommandInvoker { Future generatePage(String code, String fileName, {var args}) { if (args is String) { var path = args == 'SCREEN' - ? '$_screenDirectoryPath$fileName.dart' - : '$_viewDirectoryPath$fileName.dart'; // Removed .g - pageWriter.write(code, path); + ? p.join(_screenDirectoryPath, fileName) + : p.join(_viewDirectoryPath, fileName); + pageWriter.write(code, p.setExtension(path, '.dart')); } return Future.value(); } - String getViewPath(String fileName) => '$_viewDirectoryPath$fileName.dart'; + String getViewPath(String fileName) => + p.setExtension(p.join(_viewDirectoryPath, fileName), '.dart'); @override void commandCreated(FileStructureCommand command) { command.write(this); } + ///Going to run any [writeDataToFile] calls that just executed in [_inDryRunMode]. + void writeDryRunCommands() { + _dryRunMethodCalls.forEach((funcParams) => writeDataToFile( + funcParams.item1, funcParams.item2, funcParams.item3, + UUID: funcParams.item4)); + _dryRunMethodCalls.clear(); + } + + void clearDryRunCommands() => _dryRunMethodCalls.clear(); + /// Writing [data] into [directory] with the file [name] /// /// The [name] parameter should include the name of the file and the @@ -139,11 +182,20 @@ abstract class FileStructureStrategy implements CommandInvoker { void writeDataToFile(String data, String directory, String name, {String UUID}) { var file = getFile(directory, name); - file.createSync(recursive: true); - file.writeAsStringSync(data); - fileObservers.forEach((observer) => observer.fileCreated( - file.path, UUID ?? p.basenameWithoutExtension(file.path))); + if (_inDryRunMode) { + _dryRunMethodCalls.add(Tuple4(data, directory, name, UUID)); + if (_dryRunModeNotify) { + fileObservers.forEach((observer) => observer.fileCreated( + file.path, UUID ?? p.basenameWithoutExtension(file.path))); + } + } else { + file.createSync(recursive: true); + file.writeAsStringSync(data); + + fileObservers.forEach((observer) => observer.fileCreated( + file.path, UUID ?? p.basenameWithoutExtension(file.path))); + } } /// Appends [data] into [directory] with the file [name] diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 8aa460c6..4cd5e660 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -69,15 +69,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { return node; } - Future conditionsToApplyMiddleware( - PBIntermediateNode node) async { - if ((node is PBSharedInstanceIntermediateNode && _isMasterState(node)) || - (node?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false)) { - return await applyMiddleware(node); - } - return node; - } - bool _isMasterState(PBSharedInstanceIntermediateNode node) { if (node.isMasterState) { return true; @@ -87,25 +78,15 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { return symbolMaster?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false; } - Future _applyMiddlewareToNode( - PBIntermediateNode node) async { - var stack = [node]; - while (stack.isNotEmpty) { - var currentNode = stack.removeLast(); - - /// Add all children to the stack - if (currentNode.child != null) { - stack.add(currentNode.child); - } else if (currentNode is PBLayoutIntermediateNode) { - currentNode.children.forEach((node) { - stack.add(node); - }); + ///Applying the registered [Middleware] to all the [PBIntermediateNode]s within the [PBIntermediateTree] + Future _applyMiddleware(PBIntermediateTree tree) async { + for (var node in tree) { + if ((node is PBSharedInstanceIntermediateNode && _isMasterState(node)) || + (node?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false)) { + await applyMiddleware(node); } - - /// Apply incoming function to all nodes - await conditionsToApplyMiddleware(currentNode); } - return node; + return tree; } ///Generates the [PBIntermediateTree]s within the [pb_project] @@ -125,18 +106,19 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var fileName = tree.identifier?.snakeCase ?? 'no_name_found'; // Relative path to the file to create - var relPath = '${tree.name.snakeCase}/$fileName'; + var relPath = p.join(tree.name.snakeCase, '$fileName.dart'); + // Change relative path if current tree is part of multi-platform setup if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { var platformFolder = poLinker.stripPlatform(tree.rootNode.managerData.platform); - relPath = '$fileName/$platformFolder/$fileName'; + relPath = p.join(fileName, platformFolder, '$fileName'); } if (tree.rootNode is InheritedScaffold && (tree.rootNode as InheritedScaffold).isHomeScreen) { - await _setMainScreen(tree, '$relPath.dart'); + await _setMainScreen(tree, relPath); } - await _applyMiddlewareToNode(tree.rootNode); + await _applyMiddleware(tree); var command; if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { @@ -172,7 +154,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { tree.UUID, '$fileName.dart', generationManager.generate(tree.rootNode), - relativePath: tree.name.snakeCase + '/', + relativePath: '${tree.name.snakeCase}/', ); if (_importProcessor.imports.isNotEmpty) { diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart index f4777a12..30e68d3a 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart @@ -21,7 +21,7 @@ class IntermediateDFSIterator bool moveNext() { if (_stack.isNotEmpty) { _currentElement = _stack.removeAt(0); - _stack.addAll((_currentElement.children ?? []).cast()); + _stack.addAll((_currentElement?.children ?? []).cast()); return true; } return false; From 4c7d08edf5dc88e4b98a0fb564b14a8cc02b9bee Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Tue, 25 May 2021 22:17:56 -0700 Subject: [PATCH 138/404] Outputs fonts to .yaml file and log.info of fonts that need to be copied. --- .../pb_generation_configuration.dart | 2 +- .../visual-widgets/pb_text_gen.dart | 4 +- .../generators/writers/pb_flutter_writer.dart | 71 ++++++++++++++++++- .../generators/writers/pb_page_writer.dart | 4 ++ .../writers/pb_traversal_adapter_writer.dart | 6 ++ .../entities/style/font_descriptor.dart | 2 + .../sketch/entities/style/shared_style.dart | 4 +- .../sketch/entities/style/text_style.dart | 12 ++-- .../entities/inherited_text.dart | 4 +- 9 files changed, 94 insertions(+), 15 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index eaaa8d24..2680c6ef 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -152,7 +152,7 @@ abstract class GenerationConfiguration { Future _commitDependencies(String projectName) async { var writer = _pageWriter; if (writer is PBFlutterWriter) { - writer.submitDependencies(projectName + '/pubspec.yaml'); + await writer.submitDependencies(projectName + '/pubspec.yaml'); } } diff --git a/lib/generation/generators/visual-widgets/pb_text_gen.dart b/lib/generation/generators/visual-widgets/pb_text_gen.dart index 4c95ff96..a92a7355 100644 --- a/lib/generation/generators/visual-widgets/pb_text_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_text_gen.dart @@ -36,8 +36,8 @@ class PBTextGen extends PBGenerator with PBColorMixin { } buffer.write('TextStyle(\n'); - if (source.fontName != null) { - buffer.write('fontFamily: \'${source.fontName}\',\n'); + if (source.fontFamily != null) { + buffer.write('fontFamily: \'${source.fontFamily}\',\n'); } if (source.fontSize != null) { buffer.write('fontSize: ${source.fontSize.toString()},\n'); diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index 0fabd606..bd31ccf7 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -1,6 +1,8 @@ import 'dart:io'; +import 'package:quick_log/quick_log.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; +import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; ///Responsible for writing code into files in the desired folder structure class PBFlutterWriter implements PBPageWriter { @@ -10,12 +12,25 @@ class PBFlutterWriter implements PBPageWriter { factory PBFlutterWriter() => _instance; + var log = Logger('PBFlutterWriter'); @override Map dependencies = {}; + + @override + Map> fonts = {}; + @override void addDependency(String packageName, String version) => dependencies[packageName] = version; + @override + void addFont(FontDescriptor fd) { + if (!fonts.containsKey(fd.fontFamily)) { + fonts[fd.fontFamily] = {}; + } + fonts[fd.fontFamily][fd.fontName] = fd; + } + ///[fileAbsPath] should be the absolute path of the file @override void write(String code, String fileAbsPath) { @@ -66,12 +81,12 @@ class MyApp extends StatelessWidget { await mainFile.close(); } - void submitDependencies(String yamlAbsPath) async { + Future submitDependencies(String yamlAbsPath) async { var line = 0; var readYaml = File(yamlAbsPath).readAsLinesSync(); if (dependencies.isNotEmpty) { line = readYaml.indexOf('dependencies:'); - if (line > 0) { + if (line >= 0) { dependencies.forEach((packageName, version) { if (!readYaml.contains(' ${packageName}: ${version}')) { readYaml.insert(++line, ' ${packageName}: ${version}'); @@ -82,11 +97,61 @@ class MyApp extends StatelessWidget { } } line = readYaml.indexOf('flutter:'); - if (line > 0) { + if (line >= 0) { if (!readYaml.contains(' assets:')) { readYaml.insert(++line, ' assets:\n - assets/images/'); } } + + // add any fonts to the .yaml file, end-user will need to copy the fonts to the directory + if (fonts.isNotEmpty) { + line = readYaml.indexOf('fonts:'); + if (line < 0) { + readYaml.add('fonts:'); + line = readYaml.length - 1; + } + line++; + fonts.forEach((fontFamily, fontNameMap) { + var familyLine = readYaml.indexOf(' - family: $fontFamily'); + if (familyLine < 0) { + familyLine = line; + readYaml.insert(line, ' - family: $fontFamily'); + } + // find the end of this yaml block for - family: + var endFamilyLine = readYaml.indexWhere((element) => + element.startsWith(' - family: '), familyLine + 1); + if (endFamilyLine < 0) { + endFamilyLine = readYaml.length; + } + + var fontsLine = readYaml.indexOf(' fonts:', familyLine); + if ((fontsLine < 0) || (fontsLine >= endFamilyLine)) { + fontsLine = familyLine + 1; + readYaml.insert(fontsLine, ' fonts:'); + } + + // run through the actual font files to load + fontNameMap.forEach((fontName, fd) { + var fontPath = '${MainInfo().outputPath}${MainInfo().projectName}/assets/fonts/$fontFamily'; + if (!File('$fontPath/$fontName.ttf').existsSync()) { + log.info('Please copy missing $fontName.ttf to $fontPath/'); + } + + var assetLine = readYaml.indexOf( + ' - asset: fonts/$fontFamily/$fontName.ttf', familyLine); + if ((assetLine < 0) || (assetLine >= endFamilyLine)) { + readYaml.insert( + ++fontsLine, ' - asset: fonts/$fontFamily/$fontName.ttf'); + // add weight but not w prefix that flutter requires. + readYaml.insert(++fontsLine, ' weight: ${fd.fontWeight.substring(1)}'); + if (fd.fontStyle == 'italic') { + readYaml.insert(++fontsLine, ' style: italic'); + } + } + }); + }); + } + var writeYaml = File(yamlAbsPath).openWrite(mode: FileMode.write); for (var i = 0; i < readYaml.length; ++i) { diff --git a/lib/generation/generators/writers/pb_page_writer.dart b/lib/generation/generators/writers/pb_page_writer.dart index 60293e02..00e47fbc 100644 --- a/lib/generation/generators/writers/pb_page_writer.dart +++ b/lib/generation/generators/writers/pb_page_writer.dart @@ -1,6 +1,10 @@ +import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; + abstract class PBPageWriter { Map dependencies = {}; + Map> fonts = {}; void write(String code, String fileName); void addDependency(String packageName, String version); + void addFont(FontDescriptor fd); } diff --git a/lib/generation/generators/writers/pb_traversal_adapter_writer.dart b/lib/generation/generators/writers/pb_traversal_adapter_writer.dart index 67987ac4..3cde88e9 100644 --- a/lib/generation/generators/writers/pb_traversal_adapter_writer.dart +++ b/lib/generation/generators/writers/pb_traversal_adapter_writer.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; +import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; /// Adapter used to traverse trees using generation /// without actually writing to the tree itself. @@ -10,6 +11,11 @@ class PBTraversalAdapterWriter extends PBPageWriter { return; } + @override + void addFont(FontDescriptor fd) { + return; + } + @override void write(String code, String fileName) { return; diff --git a/lib/input/sketch/entities/style/font_descriptor.dart b/lib/input/sketch/entities/style/font_descriptor.dart index c82350ca..8994125d 100644 --- a/lib/input/sketch/entities/style/font_descriptor.dart +++ b/lib/input/sketch/entities/style/font_descriptor.dart @@ -9,6 +9,8 @@ class FontDescriptor implements PBFontDescriptor { Map rawAttributes; @override @JsonKey(ignore: true) + String fontFamily; + @JsonKey(ignore: true) String fontName; @override @JsonKey(ignore: true) diff --git a/lib/input/sketch/entities/style/shared_style.dart b/lib/input/sketch/entities/style/shared_style.dart index 709cf390..040904e8 100644 --- a/lib/input/sketch/entities/style/shared_style.dart +++ b/lib/input/sketch/entities/style/shared_style.dart @@ -94,8 +94,8 @@ class SharedStyle with PBColorMixin { var ts = style.textStyle; var fd = ts.fontDescriptor as FontDescriptor; buffer.write('TextStyle(\n'); - if (fd.fontName != null) { - buffer.write('fontFamily: \'${fd.fontName}\',\n'); + if (fd.fontFamily != null) { + buffer.write('fontFamily: \'${fd.fontFamily}\',\n'); } if (fd.fontSize != null) { buffer.write('fontSize: ${fd.fontSize.toString()},\n'); diff --git a/lib/input/sketch/entities/style/text_style.dart b/lib/input/sketch/entities/style/text_style.dart index b2dc1956..8f079b96 100644 --- a/lib/input/sketch/entities/style/text_style.dart +++ b/lib/input/sketch/entities/style/text_style.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/design_logic/color.dart'; import 'package:parabeac_core/design_logic/pb_font_descriptor.dart'; import 'package:parabeac_core/design_logic/pb_paragraph_style.dart'; import 'package:parabeac_core/design_logic/pb_text_style.dart'; +import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/input/sketch/entities/style/color.dart'; import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; import 'package:parabeac_core/input/sketch/entities/style/paragraph_style.dart'; @@ -79,17 +80,18 @@ class TextStyle implements PBTextStyle { //Find if text has special weight for (var s in STYLES) { + var fd = fontDescriptor as FontDescriptor; if (fontDescriptor.fontName.contains(s)) { // this is really a mapping of style to weight - (fontDescriptor as FontDescriptor).fontWeight = + fd.fontWeight = fontInfo[s]['fontWeight']; // this is only normal, italic style - (fontDescriptor as FontDescriptor).fontStyle = fontInfo[s]['fontStyle']; + fd.fontStyle = fontInfo[s]['fontStyle']; // this is really fontFamily with removal of -XXX font type name suffix - (fontDescriptor as FontDescriptor).fontName = - fontDescriptor.fontName.replaceFirst('-$s', ''); - (fontDescriptor as FontDescriptor).letterSpacing = + fd.fontFamily = fd.fontName.replaceFirst('-$s', ''); + fd.letterSpacing = rawEncodedAttributes['kerning'] ?? 0.0; + PBFlutterWriter().addFont(fd); break; } } diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 47b01a82..619dd142 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -25,7 +25,7 @@ class InheritedText extends PBVisualIntermediateNode String text; num fontSize; - String fontName; + String fontFamily; String fontWeight; // one of the w100-w900 weights String fontStyle; // normal, or italic String textAlignment; @@ -54,7 +54,7 @@ class InheritedText extends PBVisualIntermediateNode } fontSize = originalRef.style.textStyle.fontDescriptor.fontSize; auxiliaryData.color = toHex(originalRef.style.textStyle.fontColor); - fontName = originalRef.style.textStyle.fontDescriptor.fontName; + fontFamily = originalRef.style.textStyle.fontDescriptor.fontFamily; fontWeight = originalRef.style.textStyle.fontDescriptor.fontWeight; fontStyle = originalRef.style.textStyle.fontDescriptor.fontStyle; letterSpacing = originalRef.style.textStyle.fontDescriptor.letterSpacing; From f3aa8fe4fc311d754c9948c31b938511da457a92 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Tue, 25 May 2021 22:25:13 -0700 Subject: [PATCH 139/404] Revert "Outputs fonts to .yaml file and log.info of fonts that need to be copied." This reverts commit 4c7d08edf5dc88e4b98a0fb564b14a8cc02b9bee. --- .../pb_generation_configuration.dart | 2 +- .../visual-widgets/pb_text_gen.dart | 4 +- .../generators/writers/pb_flutter_writer.dart | 71 +------------------ .../generators/writers/pb_page_writer.dart | 4 -- .../writers/pb_traversal_adapter_writer.dart | 6 -- .../entities/style/font_descriptor.dart | 2 - .../sketch/entities/style/shared_style.dart | 4 +- .../sketch/entities/style/text_style.dart | 12 ++-- .../entities/inherited_text.dart | 4 +- 9 files changed, 15 insertions(+), 94 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 2680c6ef..eaaa8d24 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -152,7 +152,7 @@ abstract class GenerationConfiguration { Future _commitDependencies(String projectName) async { var writer = _pageWriter; if (writer is PBFlutterWriter) { - await writer.submitDependencies(projectName + '/pubspec.yaml'); + writer.submitDependencies(projectName + '/pubspec.yaml'); } } diff --git a/lib/generation/generators/visual-widgets/pb_text_gen.dart b/lib/generation/generators/visual-widgets/pb_text_gen.dart index a92a7355..4c95ff96 100644 --- a/lib/generation/generators/visual-widgets/pb_text_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_text_gen.dart @@ -36,8 +36,8 @@ class PBTextGen extends PBGenerator with PBColorMixin { } buffer.write('TextStyle(\n'); - if (source.fontFamily != null) { - buffer.write('fontFamily: \'${source.fontFamily}\',\n'); + if (source.fontName != null) { + buffer.write('fontFamily: \'${source.fontName}\',\n'); } if (source.fontSize != null) { buffer.write('fontSize: ${source.fontSize.toString()},\n'); diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index bd31ccf7..0fabd606 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -1,8 +1,6 @@ import 'dart:io'; -import 'package:quick_log/quick_log.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; -import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; ///Responsible for writing code into files in the desired folder structure class PBFlutterWriter implements PBPageWriter { @@ -12,25 +10,12 @@ class PBFlutterWriter implements PBPageWriter { factory PBFlutterWriter() => _instance; - var log = Logger('PBFlutterWriter'); @override Map dependencies = {}; - - @override - Map> fonts = {}; - @override void addDependency(String packageName, String version) => dependencies[packageName] = version; - @override - void addFont(FontDescriptor fd) { - if (!fonts.containsKey(fd.fontFamily)) { - fonts[fd.fontFamily] = {}; - } - fonts[fd.fontFamily][fd.fontName] = fd; - } - ///[fileAbsPath] should be the absolute path of the file @override void write(String code, String fileAbsPath) { @@ -81,12 +66,12 @@ class MyApp extends StatelessWidget { await mainFile.close(); } - Future submitDependencies(String yamlAbsPath) async { + void submitDependencies(String yamlAbsPath) async { var line = 0; var readYaml = File(yamlAbsPath).readAsLinesSync(); if (dependencies.isNotEmpty) { line = readYaml.indexOf('dependencies:'); - if (line >= 0) { + if (line > 0) { dependencies.forEach((packageName, version) { if (!readYaml.contains(' ${packageName}: ${version}')) { readYaml.insert(++line, ' ${packageName}: ${version}'); @@ -97,61 +82,11 @@ class MyApp extends StatelessWidget { } } line = readYaml.indexOf('flutter:'); - if (line >= 0) { + if (line > 0) { if (!readYaml.contains(' assets:')) { readYaml.insert(++line, ' assets:\n - assets/images/'); } } - - // add any fonts to the .yaml file, end-user will need to copy the fonts to the directory - if (fonts.isNotEmpty) { - line = readYaml.indexOf('fonts:'); - if (line < 0) { - readYaml.add('fonts:'); - line = readYaml.length - 1; - } - line++; - fonts.forEach((fontFamily, fontNameMap) { - var familyLine = readYaml.indexOf(' - family: $fontFamily'); - if (familyLine < 0) { - familyLine = line; - readYaml.insert(line, ' - family: $fontFamily'); - } - // find the end of this yaml block for - family: - var endFamilyLine = readYaml.indexWhere((element) => - element.startsWith(' - family: '), familyLine + 1); - if (endFamilyLine < 0) { - endFamilyLine = readYaml.length; - } - - var fontsLine = readYaml.indexOf(' fonts:', familyLine); - if ((fontsLine < 0) || (fontsLine >= endFamilyLine)) { - fontsLine = familyLine + 1; - readYaml.insert(fontsLine, ' fonts:'); - } - - // run through the actual font files to load - fontNameMap.forEach((fontName, fd) { - var fontPath = '${MainInfo().outputPath}${MainInfo().projectName}/assets/fonts/$fontFamily'; - if (!File('$fontPath/$fontName.ttf').existsSync()) { - log.info('Please copy missing $fontName.ttf to $fontPath/'); - } - - var assetLine = readYaml.indexOf( - ' - asset: fonts/$fontFamily/$fontName.ttf', familyLine); - if ((assetLine < 0) || (assetLine >= endFamilyLine)) { - readYaml.insert( - ++fontsLine, ' - asset: fonts/$fontFamily/$fontName.ttf'); - // add weight but not w prefix that flutter requires. - readYaml.insert(++fontsLine, ' weight: ${fd.fontWeight.substring(1)}'); - if (fd.fontStyle == 'italic') { - readYaml.insert(++fontsLine, ' style: italic'); - } - } - }); - }); - } - var writeYaml = File(yamlAbsPath).openWrite(mode: FileMode.write); for (var i = 0; i < readYaml.length; ++i) { diff --git a/lib/generation/generators/writers/pb_page_writer.dart b/lib/generation/generators/writers/pb_page_writer.dart index 00e47fbc..60293e02 100644 --- a/lib/generation/generators/writers/pb_page_writer.dart +++ b/lib/generation/generators/writers/pb_page_writer.dart @@ -1,10 +1,6 @@ -import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; - abstract class PBPageWriter { Map dependencies = {}; - Map> fonts = {}; void write(String code, String fileName); void addDependency(String packageName, String version); - void addFont(FontDescriptor fd); } diff --git a/lib/generation/generators/writers/pb_traversal_adapter_writer.dart b/lib/generation/generators/writers/pb_traversal_adapter_writer.dart index 3cde88e9..67987ac4 100644 --- a/lib/generation/generators/writers/pb_traversal_adapter_writer.dart +++ b/lib/generation/generators/writers/pb_traversal_adapter_writer.dart @@ -1,5 +1,4 @@ import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; -import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; /// Adapter used to traverse trees using generation /// without actually writing to the tree itself. @@ -11,11 +10,6 @@ class PBTraversalAdapterWriter extends PBPageWriter { return; } - @override - void addFont(FontDescriptor fd) { - return; - } - @override void write(String code, String fileName) { return; diff --git a/lib/input/sketch/entities/style/font_descriptor.dart b/lib/input/sketch/entities/style/font_descriptor.dart index 8994125d..c82350ca 100644 --- a/lib/input/sketch/entities/style/font_descriptor.dart +++ b/lib/input/sketch/entities/style/font_descriptor.dart @@ -9,8 +9,6 @@ class FontDescriptor implements PBFontDescriptor { Map rawAttributes; @override @JsonKey(ignore: true) - String fontFamily; - @JsonKey(ignore: true) String fontName; @override @JsonKey(ignore: true) diff --git a/lib/input/sketch/entities/style/shared_style.dart b/lib/input/sketch/entities/style/shared_style.dart index 040904e8..709cf390 100644 --- a/lib/input/sketch/entities/style/shared_style.dart +++ b/lib/input/sketch/entities/style/shared_style.dart @@ -94,8 +94,8 @@ class SharedStyle with PBColorMixin { var ts = style.textStyle; var fd = ts.fontDescriptor as FontDescriptor; buffer.write('TextStyle(\n'); - if (fd.fontFamily != null) { - buffer.write('fontFamily: \'${fd.fontFamily}\',\n'); + if (fd.fontName != null) { + buffer.write('fontFamily: \'${fd.fontName}\',\n'); } if (fd.fontSize != null) { buffer.write('fontSize: ${fd.fontSize.toString()},\n'); diff --git a/lib/input/sketch/entities/style/text_style.dart b/lib/input/sketch/entities/style/text_style.dart index 8f079b96..b2dc1956 100644 --- a/lib/input/sketch/entities/style/text_style.dart +++ b/lib/input/sketch/entities/style/text_style.dart @@ -3,7 +3,6 @@ import 'package:parabeac_core/design_logic/color.dart'; import 'package:parabeac_core/design_logic/pb_font_descriptor.dart'; import 'package:parabeac_core/design_logic/pb_paragraph_style.dart'; import 'package:parabeac_core/design_logic/pb_text_style.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/input/sketch/entities/style/color.dart'; import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; import 'package:parabeac_core/input/sketch/entities/style/paragraph_style.dart'; @@ -80,18 +79,17 @@ class TextStyle implements PBTextStyle { //Find if text has special weight for (var s in STYLES) { - var fd = fontDescriptor as FontDescriptor; if (fontDescriptor.fontName.contains(s)) { // this is really a mapping of style to weight - fd.fontWeight = + (fontDescriptor as FontDescriptor).fontWeight = fontInfo[s]['fontWeight']; // this is only normal, italic style - fd.fontStyle = fontInfo[s]['fontStyle']; + (fontDescriptor as FontDescriptor).fontStyle = fontInfo[s]['fontStyle']; // this is really fontFamily with removal of -XXX font type name suffix - fd.fontFamily = fd.fontName.replaceFirst('-$s', ''); - fd.letterSpacing = + (fontDescriptor as FontDescriptor).fontName = + fontDescriptor.fontName.replaceFirst('-$s', ''); + (fontDescriptor as FontDescriptor).letterSpacing = rawEncodedAttributes['kerning'] ?? 0.0; - PBFlutterWriter().addFont(fd); break; } } diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 619dd142..47b01a82 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -25,7 +25,7 @@ class InheritedText extends PBVisualIntermediateNode String text; num fontSize; - String fontFamily; + String fontName; String fontWeight; // one of the w100-w900 weights String fontStyle; // normal, or italic String textAlignment; @@ -54,7 +54,7 @@ class InheritedText extends PBVisualIntermediateNode } fontSize = originalRef.style.textStyle.fontDescriptor.fontSize; auxiliaryData.color = toHex(originalRef.style.textStyle.fontColor); - fontFamily = originalRef.style.textStyle.fontDescriptor.fontFamily; + fontName = originalRef.style.textStyle.fontDescriptor.fontName; fontWeight = originalRef.style.textStyle.fontDescriptor.fontWeight; fontStyle = originalRef.style.textStyle.fontDescriptor.fontStyle; letterSpacing = originalRef.style.textStyle.fontDescriptor.letterSpacing; From ddc69ef5c83f538ba5221ded9976cbcec9fd850a Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Tue, 25 May 2021 22:25:29 -0700 Subject: [PATCH 140/404] Revert "test file updated" This reverts commit 2d8b863e6ee739123a02de526173611db0a63dd5. --- test/assets/SymbolTest-simp.sketch | Bin 26536 -> 26493 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/assets/SymbolTest-simp.sketch b/test/assets/SymbolTest-simp.sketch index 699538adc2e8bc2cfb78c4543a5b157a114eabd8..5e3cbde60e11292502bc9b9d92eb07db273056af 100644 GIT binary patch literal 26493 zcmeGCgL7q1^frn|6Wg{YwlPU2PA0Z(p4hhSiETR*+qP}{p3nDve^tNt{s*`2-BqV{ zpRRtod#~=j*0Y}8f26@7&_TdJph5n-E?B)%Ip9D*W@JG?5P<)U?Ti36CbrHDmQHrI zm)aUm>%URIeliG{H98S_WU?MsX1CHUc3%{0Gr>rzE0M!NpjqjBT(5&~@zg`o*$py( z2*I(Yof@_GToJa<@~kTbNTb8ilR2S0u0gN9rDrYW2Ddn?h`Dn3n-XM+kgCG+7|TPbTn)!bQF1Y zV6MsJ1h|{GS4T?z_#oI`nsOKzW6pejM?@E_TGmQ#tY7FN1Po2Cl_?rnXV|X@1h}O2^baQ%;-rV=0IA@z7Lr0#SUVcsC zV`U*YQ=W=3(@-;dI^ziTDx0xhf86C3^WLNZe|a%~l#F#+K8nEKFPAYU{I_RHT)hCP zT%gzul=##S$}pv^KN})hISCKwzgTc(8wtgRVD_Zkj5X}3(@$!X=imlCpdA#pRQZ2! z6RgQ%6I8Zv5vSCOZdgQF=R-QsMWJHCQT{?QV6ZFKphCIxvyIaFNjeWHMg@vN7d>K- zE2gg+NTER}i!|hE-V?jT&m0FJcV{xN09}i{3YEB(vRq-I;JW9-Ta5Rfl_3!*)F&C)I)H64 zL4HRb-dm7N8zz9wMn6Q<-X~8u8w~&z+DC9J>4jyB#i@_54B{UOfgQqN*7M`*Vk$`l z!Tdi_1{_FRx2!6*D zNu8EZM6O^WqX&M5Hi)>-6TZvrBnsoN3~_uI;8uw9h@3$nCqP*qd`teW?c+YOgx?&tR zf9^f!<7{u(b#{0Q=H@i(q!4B9-_GyD#IiMY(wsTYxwyrZmztV<)(UWHYgB-W)Pe`o zjK>@NQT1PPOz5YV(=f{mItxT&Z+EtJt2V7w8TCFYeZB=wV9VphrJ0`3AG(v2y}Roe$Wxgp*CiEiK_$(g zu9JL` zuUwFVl$rMTziB`6pnOR?yD$5bA z6tN7bYb_g+_Px&OWN`OBPMplT7h|r@=$H&rTXa5_T!i=9-78L;@ZD~vL&7>o>wG06 zqX9!qeAQ9gUg&0vz?~P}1V7enZf3>`=&OX)QctI?#N|#edwkI+KcPm5r zn~BmL(oZ%|kp%x{9Xkd!#6v+e*9{LVhv^clG0;H^ zDVcf~K0b+))+S=)*I1BYoG5E?w3IQ^RbOi^N(;;_m{UaQ4J_Rhbz$;^MT8Q3f^Mu9 zm-kq!2G+i50)z}q1mEGD5F|7TL^-=~@M0W<`ykXlVbnWLJTEucYnb@ZZzfwhw7Gas z(L$1me!E)np-;>Z4EH|XlJ%)p5HZriF3Fu=ISy}H^O-Lsj$oXoG!@HQnOp8MmflOAICraS_ zDY3jnPv}CoE}Jn~oSPzr%n-*M5BkL&Xw8N~gCVx3OP+seZeJvr{&VtZ(b2US;+iqj zvDx}D^ZA~mHv6gg_mfTPVq+&ZmW_<2pxyvtoZVO~>%g z&FJF{(fUjNRmt!kyp`4gUX z$RlWs{>O+aN`jnESjOxx|9K0-I%vRQEWrIZ;x_c$qdP;EXTXL`ohi+2Agn(ON-Bd@bYW(NNtBE7E|Y-7|=;k6Wlgbrm@IU>w(A_!{)PVG$#F%6} zXN+h!x49+hcy6yRFCjLdu8CM|Y@5*4ozf&cANOF#!}2VkE?#`B{Pg+9{R0iFM9*o_-t*%DEG+ggyc%2EOo)xl`0d!nJ2L!h%?s9{f+MFz1Zw^TFzVGB4O)P)9Mi6!wRo1+^(rDtI` z=aIP#KCj$84PGCb4;}5DJne^vmzU+EDd~b`O_#PRKjuHr?Ixth!PG`9&_Mp)K{@0j zLGO&~PnCvA#mdE98n-*N7958Lq!P zOhrqE8{`T)?J?;ak>jt1@f!++od^$z4kq$)UTz>cd^!gjDH*${jpPxm|( zEJTl92u!-nqCd+#HJWvOG5+~K2sU~9oo)}1SzAVefG`3Hw!MLwi4!BM2!}AMC>tmJ zFD`CTdNvjoG5TL(BBJ!H94y>SY^*HoVw_z6i-PNDIjwWmfBmH4$0OWebSDEbq&k-2 zP^xo%+MQ61h&PYKOIKD{AkRtqez%BQm~>%@Fyd|wb+;!6fxs2o?_WNFd~^rW@Nvw@ z+3{IE-f4010?Ef}kMC`-jn2Eckt~_CV^|FvzP+U4k>V*b%Cf#Jg?L&7q^_EBjhtk= zBlm1}F_joyQb#sg%)c*5@^Tg15g+@V<(aeN4c5&g>scDixyOmQ740t#w3*f}tk*4_ zwh^~-Q;dr*A_A*YFIDR3*JiILCQ6JX1}Qp6kBo!)l7f>Bj$k%=QzU3a(PI~20#TT$ zSl1P+h6@y(XAs)_I>(WF)A@X^DsARxmDIxeqa3H_V`t^39WZ*B^OoG1D?HNzol}@Z z8|Z}E(yiJDj}>>7xLqH7xN2C#8XDTht6n~x=0oPUBz8keY`OH)`((>fjYK}dk``0} zP{Jm?m@oxs1L23%3PEIc#tA12b)q-3i;J_=-{|6RlYC<>Vae50Zk$lRYw)L2n11&R z2z#>olYT$v`amzo*1WrFVqu-@0@#DgyGJsfn9ZLnZN=Rxx^R=AGjM8t-!HdE!~!s$ z*=6tdyw(~oz33<>8$Tb)K0RT4|86-bLt=k$HP=)~a)QoV?>5gZFVbg>uT~@Li~*Wd z+3LvEBe3HU9mvqXi{c4l=>oguk*<-A7bhr>dCN9!hVamlK3E{}Q9 zjln=ax!{QTo80&`SGpQoqUApon?R0r%pN=F{(Ahg$0~p+&bTv;ks`Jj<)qMtg zn46KN5+@Y;yYxY5Mopu6``tz4dAwx8d2LCg2kw4s|(OylTrlr2-4=sjuh zXnau$W0**;1kl8nTMc=O-#uwyqB3qOp0!L>!@!Utd*M`i{{g==BiJ0F`v}Lh)Lk`5 zZ|z?${@7YQ!4=PSJ66CZ%e*IrRv2jHhqT0c6$Ho;@QEt6ifSG&E*snSy?fPY&SDQ8 zKC2!ofyq*?j-MaF%aGUw(=`off`06@{97zrwlUsp&73PXIQNEb_ZRnp%Pa zube=GxYQ%<%LDXDkk3c=p|t8D*IO!bx`{7%=AM$bAe%&evFLpm)FV%r6^5v%V4$4B zM)Bhjy-;{D18Dyh&fyyQ!x)DL-fA2QAu`Rw%ftKu2@n>35|ym3jk-xaHp!%@olV1$3R*}g zZ#|*3fka35_{D@5{ia}?_UyQA9uOGQ?Dq*Wi&r!+`HDR~a%o{gZ zvPvY@bn#-C>0t9RJpLB@v79!m7=o+m)3Mh1QaATe`V&<(aZ?_Uxk7__+LNui{$uZ} z$K76x_iaGEQQk6mjjxr}Vw)EK_2=%0PB7Us>Hn{^O@sgSbN5Ck_?$4x(i@ZJMGAH_ z24^OKWts}5_-jNfz(ezs_4}n+GX-sVtaHU8|0ia2G+t5u(KWo#Kv$+}w>%i!6mhXE zY>J#^{NMtqS>>bL7+cYWsx*|~SmO7U@@eDwX%3Xs1L*XZmXSW@WbDeT*KNz~x&2RR-ocYoxNXZ=RY--CoX-FkYuI;sbuk+F$ONn?9Et1h5Y#|(! zlJg6L?YdtCw=zEEN{!ucR~Rr4;iyn*<+j6(osJ09F-C6!p8S{BA51P=sjb9WRq z5zh~?lR9NK!!f>!1{XS8DNp*Jcbz!SwSw7#(f9GGRbh`7U39~E&J(7C?(Vbo#;`UU z7s-+L-kvSp!5xIr`q5%2r0-^;mQl=q^--bmS-($Q6OG9bW4x!TB^&0yq9tgx{|odRdZ1N9eqKq~8``?VX(r znw9%C_zOhy?C^#QDdgC#qE-g_+nkf4@~v!Hb9^Dox0A73MVBKQyz9JcURAJsE-;s6 zE7nNWnx!QAPMWDS51mL9md6UJDZr?rqlL+Ay%^#{u~v|^w4SZXZvEA3tA6_gv^}vb zj;7EfHgm7DEE;IG_6Pz@Dz z)SPRf(6`Eg-|?t~@h&Db`AHz7!(C&foGRT7RcdeBjpgnWBUWGYws&I)CY4asDgI;- z_5|MzgPMr{OQQ}K!y*Q~G!WAF%)bITJ^L(M8eb*@BZX##lA1Io(IJ28nB!Rv@J%N|;&?e@WaVX!{9Y&&$L%pX|v^~HMn4}dK zSk$4ADgl$K#oWkmuZ)}jY3tkAqs?_)mkh7)TUef^nL6Cyg0hgq;Fn|iiyc#u;yyM& zlq|dntSJ@IzZ%b2mhZIq->C9-EKM-5|6Z@25ij;_%8tvHob7+d{&Qb8G?)8u|J*Wj z8O=04lM0xwCTBJrca_8-O4j}`kYiqEbWu14dZ`@@4b?nl_u-xO1#os((#Kj+5^?S9 zhcx5!?F9zZ^%)I7F$H4hjaOt^E!;A zGxpgJVW+l+=LW=z!J{MH8U0oWqQ2|_8hr)Ll25vm=pR4i{L^WO=Y!|6rF6$Gjail! z8Xb#YWtb7zdwMcxxadDzWPuZ*oUL(_?p;}^?N_kcW7HdAceuvv;}2qg06FuVdT3fC z3Sk)vv@(1cxXTo+8FnK09HK-A)?77nQOhI`%sW~^2ZVVIeAMNeYF5kP^s*3u%I={H zWp>6#YdXj5S*Qfc>YiIOQ>Tso5(ANnCe<%p6MH~|NkXYWffhA)CNJ2w=7ex^E0x1PKU7q@uMlG=oFgz5H#8sIT8k zi~vZsCkGZq%>?okjOSr9h%emIbC2Gd*rZ6$)vqF+UnxD=oc`}=rb zQQ}eD=ZcJp#EbUw2CXGb5Y_O{=pml4{cG4)H2=HEA6&DkM66p>ro#2*44<~wH=q}B zLpUlV0Xq~)$%FGh?XJA!{Rx!@(G#WYr>F~zy*WSXy3VH+qhh2hBQ zp2GVUoKPX}ExFQgw;nk=&+Xinw{NO@%pR+IFvbw4UOZtxpTY|y&rlD-WKouH&FZpb z_hKQq@x72G&-Zy6IemzHe7Ve?b*r`~qY0S!Vw9rQ&-_1VrjZv+k(ENo<>00fygh6$ zmT(3kk)D>Lqs%L60(yc^vX%noz@dDpqBJP>*bys*QnP<+mY};!HL7GO&Gh$K0N;OC z2hEz&Ay6O6hse4Ocqee^vv`WxBZ??u8xXNJN5T?)acQZX8>Ce=z$wK zS`zwRSf|=r;@kwb-*k{>{9u-0`!!37=wUyKWEzV`{c6GgZ8^<6=ZJdOQGd>z7FvP zZJ8`*4xP3RstTn}a5cxb+rifVy7{SFtPmhQm@XtIZbpm@YRpxu2xAEWJ0v@UbbA!y z&GpZpVg6$NA+}q_DVD`H``1=U(7XC7R7S6N#@A;Fk*APXEXx%>+4u1|(|bYu+1WSf z|CtM3^E=F0L4kn868-<@f}&zfqU>C(Z1f_`TwL^Q+`qZ#xqtoUrWfJlU}5555#?a! zWdC2ep!&MwMk~rE21f3WP;w!^1w7D%Iu6x~JM-+&fuaBj^AMC!{rJ2hjl~a7T=L_8 z@w6ItOAgu}%nGhtD5^e@z z5=p_-dm2Fy1>Mr0K^}B|k}aBQQcKr(i&9EwYi&YXZAva0ucZ-IpJmEO(YDb}4pbF# z2>dFmY~^kh>vvc>cpCiI?}eI5M-4fyJUwcI3jHPZKka@VYNs`ahDg~ezgJ(#yseD1 zgREyl@@zVlq*%S|(s7(?>F88UaT%>2hB>qdRkYuw*6YIRxE3dyAf(Xt5zacp)|7wlkVV}!XpZn+mgH`bkbAw7Tn1d_%=7E-lIYU7YJY;@j` zgA)~>6nvpdR0vA`C>ma``imoyx%F!0CXwM>XMAgG;IFn?`wzKHRW+ym`#qaIiXm zR#@H@Raz}FsMgOQDM`D&G;As`_w?vCwd+;82y6fAfpkf^nuMQP+;i-@ihks_N^TG2 ze>g7qyKVu#wis&)I%?Zw9cd;S!X)T)7}2F%9Jf~lJtsV{Z#IKdVs)CRG>2pF7ZG95W`)Eq+kAVikyc@pCE6imye0h zLnmuJAwk)&Cyhtauu=hn`lI1G?WupZpCMros7FE<|GZ72FCev^8)A}CdJ&;aA5&A} zljZEJnEkp5npgYbtumumkmu>3v4U}S7=}!4GVxXDodTdEPC~&aM)81{x}@`W%A^Xr z6Wx(n$>f02)}xf<(Uli5(!xATtn>inS2qY8Gd7Tepnd#HoRd|TJsZP?MQ2?dapv(FXn?e_+T28k%IWpA6}Go z-v}UR(}Diver&(vRE|&wjD%526mVzaC@o}cg;mt!h~kf{1X`z-LQMo#A@do48A2OH5=hm{EBU~{$AIkgr<3PQiI1WWx@Ec)+vt?(_De~XZo=KueMrBdC z#wbC!I0xfyF<(MelSaernrFxSLMv_RBksrtRufLZ`iLrGxEo=4B7;>!zzOA<+*5K} zv+6~f_W|4=2X1Y=uK9;IwoZ!H^rOzQnzlQKU)Mh-x?B|yjJ%&tfy`g$_7rNnZ+vh~W!bBsq`o=`xLZ2i80 z3Q5sB#6M`Nv}FEAct!GuqNS(d4zsQ}{npdH{gXrb_PTggJ2p!L+SRGL;AvOo{BRv# zMs$0nSke35aq*lZ<7YF^9Fkqr;pl-7I7T>&Wcs@Kn2VEW;a$Jf^4UaA(%Ti{!Z(5S zk5)R4Kf%pKl~l7ih#pd_N%gVKLkjkd8D8uMeY~A~4f?zo!j?%F9!MWg3+H;mA|p(I zbi5rV()ejGndiQ(SS8ThwETQ2PGLJh9x)KP()GMSTp?s_Mhd^}5XXZK ziiUY1MlQN~iKVz0O|ydtYQf0g8&MN=@x$M3XJ#4$U*;@xZ z!KU8mFnM;$K-^w_KcA_3LHj*zgT=4;6ZLAmTA2=Y86uf)_*a=j;0>`^mMI^~tfBMVfI?7V-CS0)R!2|IqedD&;7y;4@3bWK! zbtGIvP-$ghD~8?}QccP-0lt{%4Vl$oUq^8?dTui7Svd9~mo;sq{@c4NC(Y{+#{Jhj zcWhTXS!T%8O;et%VxvqqoRQQW& zyzR8^XXs{<`5=uLYO=#2IM*SC{ZE>MG)Q8S0xl;x!(DmmSN#1MUk|56J$R(aFvOoh z(Y-^GP+Okx+O%M_>X5&WVjMCLmu6WZmaQY*v9JQBypc8afw>Tv>nL~&CcMiE8lz;~ zE{^{e$99Y_TrSPuXbAC25C-D}NkmI^>^nLws#a_Uly!*U9DdD<2Ipp+gkS(JAR-57%S3=6# zoh$_*r%WMuBPJ<0drJB`N6P*Oz7u=4gkR}vf5q|s4Zzxj3Q%5%JM$xM3jFIRwmoLB z`1fg~Hv!R1apg$1@jkdzQr z1OWk+0|5aWfQAItn8mG10dJsAisHXOs;BTzfj$L9QdC&k4fJvo#!DNp_(6ibUr)N!My>4{R$y{x;^}KuLj&izYdP>Leouv^P2!Vh?AfL1d zS@e_`|AIgk0`aF7vcLQNUv)h?F;@eGkt49yZ|8vD4+IR_m`2Fn6lUlEn%EDdZ`AWY z?1-Y@&ID@IC<+h~koXL2L>yNH(w9zwok#|RKu}!+8wn9hg9fllGf|2IA<%ML;J^-q zQotb0QuJkFfDq)YPN@IJruzXsMc0>x4}=hNxg!Bb0n>m*&e8~A<_7i)oEYK%H?jZc zS&aHwj>&4tI-T9K`Pp_(5aRB){@B4Ni^GYVhHWM zC7(~hW-5fUrGB!MDfD@B)Iu#gnD<(0QPHO5DiC?ciaH9qO9pgh0>TLq)J8kcD zMg)a`6!F`^hgUfY2LY@8v7tvW3V4KUaN-Z-z6Z;6mGq})jO0B5gE-DZJN5Mrs0AWW6%4$g@XCgY%?}J*tNV z{?%z6uro1Uze1-xJ$5?RcHm5Nx*=D7Mi_ra^DHU0C___YoiulM$N{GSQuW}hCSfKX z=v;$KRVD43kWzd-GA8z@C~yW#gZDa&oR|G$1`d-s75Mrvu)~??ZnDp7WfHB^rf%RtN84N9Ei5LfEYQSm84v6~$$4 z!c_76+dE6~PkYdShF-Xp?ZNBQ^2DjyVs4kUB1PV>n6K`r(>Ibo%+~(a^_$Cu&WpoE zp09sD-F_sZw}bR)oM2oW-?=ipl|>Qy_AErT)#TRb*IPqKjjN6Xx#p7SOl~LSB(EFa zD;CoW0Y?CdOt~a=ZSqndlNy%TOsZ(`K7}k{q#6BA#BbSj(OPxgjn&S0(?r2HDG0Uak+;j`vaJ}Aiyd4yb z???JRh?BT#m=?I}*#1um?~h}_!!GC@5r*DV2@&0ZJ{`ZSW~A|v z5Gcnv2@Q>OZMVMI!m=`jZjXQA^==MES=Wnd-->c?YvGOy3b_epIqs@gUDw^MkSj}T zv_I9VBIZx5#AEPj=;?vq;?ANBM-%X>Qp#X6+I7FCRI1nI+u>A{mlxL8E2c2$tUYUb z=hZBq^6>JC9hVrqUi%7?)pXvKH-Ihh*) zqmcK$)2+Vf3zL5*N=$92yq@Ig+IVv0D{JguEd6Mw6Dy`t=@|?GDGjA>d%3k0kMk-c zx6iL<-xIh=Hbs|BKAL&-+QoLq;D4*KI&amhYFlqJjcS$@iFAOyat2mzco2U~YWRhC^nS^W3s=$7S(& zwr`tG4AS)H?(_19EaxV2$>%~zOw>M=YzDS3A+M>7*VhnUb!-P}b@!W;`?SmYBYmg< z*Tanb2!TO&&&Q$49PehXal<5smQ{xT#~;ll+J38CI3j~hC*p?PCU-g^`y&Sj$WC+q zLq*a>MFFoVKeHm%v~HX0*}YUf_d|mF`KDgZEjN+o)uT-Z*_-K>ElSU;wvvU##X$=s zplt8{Fgv`5yE7~9tLeObkZzVuPxN*pez-6%m&*UVBGT=Af%Se=LGq^e{i)~J7mPJ} z?fd-ReVh9-K;k$**)nok;@e=SeHM7_`|VjjN|`wl5lBA% zBKiDD37!P#bi<%gk~iSqJlBs6c40~5++?K*3&7UKvJzD!6quaB^l4x+ti)IBz8>qv zsTkxQ8iW#1A_+XyHn!BfwjPm$;?pfIF5cBp^{WK_%M*UN+5TpLB5=;@d|R_}5X>i( znG;@?14OetO1zN8^3jf`&__;FeOGmCD-M_7rOIrhF&Gu;LMxljBF5135rJ*_w$YCy zi24+KMGJ>X7bi~SNe5YMt9w2Tj>4x~!~v)QyhsSMzW=%Ur;M}5q zd<5JL*2*g#|Lq^M*FR0N%i`F%;W@v+ar{D>N>q~L=Kh$aPF`&|9#N9#CvXA3z+Rs< z`Fv`bPMVi{57BmbHF3zQF4BGeu1+<}^D zohA%Oxz8KDd3~rqObx1dfu9o}iu|GnCJE5SKY={^=g`Z-?%!1(=i& z$5jEzb`|zKnV--skSU3MV`5_qk!GK~fLU$_p?Rb^I7;zBisgdw7dnwk_y zdfeDKPTKj>mw0^|>K1)9zoU1HHEMgxp zakT83R63z=MRw;LM{DJ=z2d#jGfT!>re0h+k4zjZ;1EV-IkQn~{CG7V${xC&r#CG~WV zHYT3YvpXw!&dYLMdiu;GYv#UxU>)`bBF0$x=OU_k$rHr9-=+SmV)j{oE)pz36y&<@ zZ0)&^vZrbF7VP%zbl&VHdN1{Qe5o0kmlveB>v~MVci!>8rSMpfp>JLx-H0va#GX!P zCfmZkYRG->ylD9b-TnH-ImRh3DC_)f$#T)WUcI}7BYUfgU(=b@tvA}Z>ZP~X-j<}? znLR0;*6au5{9v@IOOcwSimH!(jck|kkJ9s9LN(-tnZ22I%}0a+W%H-NXQ;BB%3^=! zdg~{uj@~VH9q_sv^&MT(vRiaj;_$vSN!4KpCAux^t{MOLBQ{a^*|+|LWd?H5 zXms7g4S;Ny!P2%@_{iCaXSMJx=y_I_u)42SRBSR;8~QyRiFNc}CY)+Ay7?8q5xJUsd}N#5(6r3>fe(yD8Dw}|c| z2f0bN?48=4p39@GtSn`wcI}_qv+=szTIM~lo0}BtbwG9-FzQkCb`UUz+uhEn)brq% zxYbGj_*Qw|fgx_0xyom2gV?A2Ww@fOH=k;)JKgxo*efvgQ8Vk8Qd@XtN5VCoqEe+L zbr|NlwL`a_evZ4#v2IP48bWr?x#{K9S<-e@@FCiI92c@E@8jXn+%Un_wKXsCTyo|! z-;c=4Ca~rE{b{^60CTr)RUKY4|K7Om{mkz;fD$^KYX{TPKO4Lk3&P`eyKm1^LpeDG#Hc^_JkNUjZNyELh9IFOE+m^ zGe4kLb~2k+E#~_S#_^0(4#vP;LOXH(#^Wg6?63q&57jQ2dFQvHXH{Xgn%<`k$iDO^8b~i_B6-e6CGNQD1sARk#~X zYkg-T3`gTttd4(2_(F8^3Z-d>vWX+NJLSegr;~Qc^hQ=$PA8}7AiId-t1oRQ@{YZy zvbdd$bl1L@ACkrc)Or~C`|S{+4k9?&-jP&SlpO6#YtNUjix|t?l*Wd#XyJ4P^i&yq z?RxZvgYYme_yUboJ7)ia`A19K58lSC;ZQK z-!-OV&R_(WX#Gd8hjZPQIZ3hnlK-kMa3X|&K_`H;#HFtBOrb38g~lSwJ8#1Ki^W1u zfdA2g@L4IZqe2tcjF8GHr;XM+NAKsM(G=|8QM38?QMH>y2j#9E=`?RBDOyvh!vT@P zibMVM=Q(agjV6h5Ji?T-cJV^PmkVT&uH5%2pQ&!WzXq#ool0C?R*bU+#}q2Q$q|z8 z!A=}luUA}Mo}nOpuZRhxI4J+>8jmo`D!WD6*Ig5fWQpP_8WHCqeTo zB$$@ACv%X~2!1{q((o&?Tv*T`5z&^Wy?i34!7YFP$^ig_Z9Bb$@G9V zHQX)^1N>Z3uAP~D3~fqMb)12TK~;TYQ*Nouk&fTagYK^NJC>XdEe(>|<18a21hT}> zURp6t%-^Iy$toQfrzbf00)c_N5QCU&zMcv7KcNgr{!N>AasE@o{)^cu!SVm8V5UG} ztN~&AKdH+Ch-;*a0ty)rEWqVSw{e36;v|66D>gA8|4&%c00t%Ne%AkRnm`;q92rn{ z^Pd1x1XH{mVIXb}sFqo1U<0)bXk(!6!Mc6}{~u1(Z%1bQpTvJdHvorT4Ke#qZEFPL z{@*y|vH2JiV_mqUHQ&|IKhDCOn9B{okya0IN~KbS_u6n zqA!7^T8IVxM1%2U;-d*ilp2`7l1O}k`{JWYR=XaBtlVTH?N(7!leRs)r00)xzh=1Y z9`g$_HH>gMz!rOx_z(kwh4LeQp(;Ww8qR3a`(aLv5qgTR+RR4%eMXOzU~PTfWOnbz z-0W)nu=GT}O_bl4u(gE-NmUg+OSwzqLa6L>Mn=3M$}i`uk2Vs%Rp)K&!lYSv@bPDaIcL=#?+Z`j z$*hWsJ&e7wze+OQ-r!2^XA&##EwFJAJ>Zc_R8EP)l7Fg=MWh_wLfm+14#|uwYVp$M zOy)s3%poxEoDGiz1mFLBm!vi?? zENFJ~;t-`9xMFJ>3!jyXhH68~^(J@uddJ43aM;^9gWl(Bm=X3x14(eC`b**|gY{M- z>=7-hAun?wkM599;4r6Rp*nDX%^X-F(5sE7TL`>CN%qh|ZR!;G>O0RUrC{Fy70iiP zo`Is$N_0sSS5C4x6yqN5V3s}e+9o=B0}^EG>M^`)aD3eAR<1{wPiU(fH3L5J^DPA@8dY)wl{(Z zep`B53CIv0JW6NBxl}S~-cS5)%t0_3l5&3mFYsPC)STN` zQ42I~NAR{oFwnuGobxjsK>~Vx!87F4eCJ2a@gXl-iREIBbT*T!Ejn#B->O{J&zXe< z>O-UPeagQ+w34B(a7Tl(00elQ#6{s{H=sbdZ`yp-Ki^azf^3RgU1kGt1%wLa5a<oGNt@`s@xe-*HJo4VpE(Cgh_Qnak;TDrUFZS9>Tn6C13d`PwLY^h*^%_jAIn{&xk`>4P%U zr}}xj2mksrOAUtO^lD$M-R-i{^hn}f9d0EJIw?i=>Hk?# zNMSwJ+}u3aB)B>F*T00MqQ7=*m$~qFP@Z(i)XnKn1Zj;fB8~UNk3Naw*=yP8NY*7o zw-to^zN`<0Sslbl>CAtcR@VZS2#N^S*)2AexCIAoGTTbqNIZHrkp|{J zST56W){1E7mH_ukp*dInpN8gtEZt58nj&f`*LamaeJ8s+x8heniDDzk;o9Dcx&+T^ z97EiDjNTHk8{0!Vse_6kMG!^ zF<-Ob&>m8hnW>`Ebw7LT{B7t7ouA`#QL^9yxYz9ObhzEaR&PJeYH!YHml-wM6kH?t zN?VA*Cs;0Sify;3Cds!s&-JU)AR zu3T3jI!v;6O1vwiI#w4!W-}z(ik%$KBsOblzWZiq_@)M*Ui?^5Zs8ShC&BvX!jJcBnt7W9o;(}RO#Y|z+1FbA(gt5>a@b6+W4h>ABzwo>Efssc zbHu@$Xz$Mj$u0>oIxG5i-mbek&O%RVt6;6v2wg<)@~gWNG^MuoPauosG1XrWcHjEe zXfPeGTASc}iIf zsdDy*uz23#^eB->ha>j!{?#Lh7ckSiKz2Nu2UYlgwRi5}P=0G4cPb=NiEBjbSj%yvzH0_xszs zYwzoN-#_*r`?}2hHP`dp_w_vMS+mw>-S@q|Pxa-x(4!5-90K&NDYb@g1YhFUjN~_r z3(HlUc<3kU0bhD|sAkwMvlej{*Me7efywC5t8O&MH^gBY<9iWap@+Em$7m?4ms@ZI!^c37lM(;)ibtE6w>nu&-Ujz&Cezikn`P@ z@~^Rl)7`#B$4n9am>jkNvBe1tb0n;tuX)!lE0@d0sp0}hkDe7ecX`itV}(2r5GYd@ z6ajc022#S3#~(SI0(7kbO!6A5ssS1+f;3;4jY`6HUIB&~=*`*QZw`V;nh@YO#j|%Y zCwXp`trJIBSfsdhij5Rb}vFb2OU0WhA1gJc2VB%zR9=W zc*_}&w#iL6nmQ}H)i-&As~zS!WdF8pLT@~ktg10|M7ZSgfu-fWdRMSmBs=BQCi)+I z)9V*e+o2()Qk4Eun3n5mY&_GOrI*;DSn>+4egX=TodnUYi?;@q%KV;>_b*7%f?^?& zR?f_qUSHT=aO)lmTJ~3+L9jr20`VI~Mq>K3;!5-E#Kfbw74>8Gp?S+4d>Qf%JEr3s z9w0!Aa5|N=?#k{nYr44vREz1ku_6k|$g;0W8SJIH`7p=hh$4-|q zI#*pQ(jVQ%l!ql*JeHlNl@C*Y2EKc&X%@4InPRiE&N`BHhjsz$J|4~5&G<9)#yk-1 zncs>$s3$Mp)?6Swpjub(z}qTjMu)MOdZar)knzHDV0sU#qZ39d^xk5NPIwZ$Z3uHA zNXiUxE35CDxMvg+=6$v}V)a(P|psSG_+lAXOHEoGpW6aRO_W8ruSEgnrCMJ`2 zdLcxjQ1dzdV#4*lNQt`GolgVNYN&Zf*=b}h%Oo!kdk3qmE1lYBE(mAY-LK9I*86BU zbN)IM{WT&hX)vhMk>#cu%1LwlT(-BDQqCH9)S!cJ)dL-pt{!_SkZET!KivAT4{Qc0 z4Y!rEdO&OTU)$6P4X>7H3+c2L7?V6{KCy+vBl#PkX1@Jr^B)K8ct_Mdav%n)dA(Uh z;3cv8cAAYqHN3Yb;Z|=FHT$j3q-S5XT$pW%tG;l{$!9zj6VMdmSRiq$kb<*X<<-b! z-2;jtAv-}f{j}oPW!s1W;yWZXA;j;qO7iwWIWY$kK_WFLIV+Wtm(d`OHlO0Oyr!*!rm0k2Q zES_kt)Pgvs(4bj}Zj0k-ZHR#QK538~b~m#$1>|NA*dcfC6EQv^iD*#Ib2vTYIfzZJ zgPVQqCqaTm2BdwFAIXxo6wzoH4#l8AL?Qkj+46P8fQ(HS=cWxW&lL16D5t;kUBiW4stIp6kMsn&b!*9Fr*Rul!83xgwXaOID#9r3&B#9nb7XJkdJj28O|qB5F~B&lD0 zaK)zPK!#;-{oyPRCQZRk=3Xm=_sEy|Oi7u7y-rK3ZkQrez{6G|=PQ-Qos6Y4A|RyW zS{40L+Jqk-L!ECnAGv(;9G>{))j7tOoz@9%|9770_H~%2|;e+z|w>k(;8cY?NZ)XScj^+9~etPPGpdzYCxo2s@M# zJQIarjUZ4ljp8lo+5BD<@zi<%-V~fvb6Tw)>G$CV&Now+U$c$LBR-Thi>=hD44lk~ z>AncAyjt*BI(ZPQmaNp20F~;=q4n&PW|Fz9jnr@MHYE0^x9J7x=UNQsx9Tgr%dW~| z$5|VVoqV#q_=7P)cT|p!w)7tCi>URFm70JkpyJjlD2|%Y^40vwf{_#kf}(Gbv!E46 z=k|Sf&3|LDrZXDME5-mdub(CuKw1vHwQ7#aDz~SyllL$N_D+GiF+nPL91gc$QDel(VXOG<0VBLpYsKuX$^534>-cDuqsqVJVJj5=Bdc3w*eTVowoa9OT!>wBqf`b(9?Naw{#{d{%Jkr>$Y zZi+eQ{la3!2VKnCa+nlaVl6Zkn_F6#OUF@%x~K(n*~DdRAeS8w1%3TWTE6RWQG9*1 zbaw8U@mVsAs}AAJ3SuH=O_g+yvRzV1hP$_%a9)EIZh04`YOC&+N@j)1>vyfW zpZ+*n+*wbeF8J%uPx=ggbEA+6i@iv#)%NA#=uoIv|FN-|8#%*-V%&uO2H9(#gE1#GSc13@k zbfV8TX6Mxsk`SdopS5`gbVIT_Ch`fYIqg~^SW;#R=fE<+w;Q$*B7{;}}-4-4g zg8%T4qNPauEEz%H*#@ODy&W}H+61{s)$r$2^~AY(tcTfj1)VwXX>)6TlS(1=^o zS{G^^JXI1gSx!S=;tu1Vzyf+p-(H+)eSL{sWu69ISXfBIwbpmM_MLZvOeA`fHuqGl z%+etb`4{O30i0!b=Br~g>8?n!=9Pr7D9NxP6l}0dk1mDAAIeRJ_|#y8nkg2KT2X)h~sSiJ!i zWpM0yM{m*m9(qOg=rJXf`De?yT^i?^3s><%CC?Frvs<_K)Mq7C2hARj2%afN$nK{f zC*s@h_n#RiC956yeHrEs|A8_r)FSZa*=#_S1S7lzgV5mJ~6|eA>xmN>k9H{ zXcBx{#}Z9xW|V=_1gTyRxKJ@=#JHMcRpRQs_E7Bz`NRe92aS?)Ja{ z(GrXvC~*?#PjCE#PiPC%<+jAj26i3_^+|YhA}4J+Hr(0A$H%ebLcj&4?{3jkJtM`_ zshRDa5q4o<&rZMe+41?HSJ5fb?{3WXFQgpIou~1i5UI{WjD`Q^P?g0o^5TN9Vv$&3r>7s`%Y(aj6*!dq^fFi-D`e(`^m2H61P7GLO0|=|+!w=?%MA`3)%7xrCT#bv!Ky|aZi_S}q zD^ph}E_?Zw)hnglsORh2y_=uF^m@M^$Kkdc*+8@^59QB{(C9Z@jNx!+?%Lpp{i-I~ z=7zCOf31+KBCwHkuqeIGhbz~$W12^>%G^rh!)H5@sJ)>?G#aX!Lw*qqY8tVqSW6uL zGjf2rk#a5tM$>?dEu8c#L*FF$7U$b}ENPY#t&F57kE|1-W`tY;QR*}t>^yE{WCCwg~n|tPUp=|KFY!yjp>oXqg)6hFjIW*{lZnRPf>Xi0EDYy^pr6Y&$-KCXu zHv9CbC3bfy1vZbDSrP|fe4(J}M^YKu^9#bv5&u13z9-`p)q}kd)Qr-T ztwHZEfm&N)aC_8#9R+95@R?!S90NXiG2uWmo0Z8y}QZxMFScg_o)%eS&~wFWCn!=ycH^U{qza>sJU6|U>msIDMSL) zi4%hi-HLB`%+EI?;T%1mta@(`A1|D1YaLJjdQ43Ikb<*HrID4!mG7VqLJ!2Ol59V3 z7Z85~9@^^{SHS9`8}vF)v(u*H#+4u_{4O>_PC(oXtSw6StH=Qpung%iOY{dv!P;aj zBi>hlS0D#O%QhTtwBbg#+4!ey3=SLP;l`Y@F^z7J!v-w<`}pv_3N#l818iT{0{A=l zvy=Up9|DV{^#=#Z*=+9^jCH2b(=p; zFM*fB{6Dp-e|7$=+}U5wJ@)*~`Ttq`>{sW%YO?(0Tt)Hk6k2{Y`&AC)FS9-+9-jXd n2l<=Xzmk7gH~aImPvxJBLD-mYT33AF*$lqvph>GS>%aaB=w8H! literal 26536 zcmeFYWmIEPvn`6dJ5A$GT_ySux)L*q`P!L@OBZyXwTg1ZG8cewO-&K={O_v8J4 zY-H{u+X=^6Z8)crH-4p`wz)Kpy zP4ZC8fK)?)UC9&(=AtqQz&V`r_@v>MUH_0}3MU>3HI-o_Fw}b*WTufSv zUBsT8S!w}X?%q}%H8C>KuY_AmQ_h3qEP#g>6fB|YW!>b5QU|7jOB+Gk%`{EQU#9B~ zUhE*5EwR=5TMVoqjJW(KGYFU8S`@`UK9~`+MrOl>=^QFgHl~LdtO9RKbGI0?^c6W6 z6xWnrR~CK%6seg2COUD`S%(N0IZO>k6CPJMH|C9Bmlq4i$l0b9V+n(U@|fbIBz@Bo z8wAM|LM8sfN=-piMXGKpt&3&nCf{O-vVM_oB9a(}-<9<;({`fCJg!TfLmcvfb5`Ee z5P;?(T$9HmtZL;ZNvjiIw~ni#lS(N5=Av;bga;(M!ybnh}Hc@HV-2~4USD8 zH)@T}OGpB<{>&yJnk*!twujCm8zJ()5fU0?M?LCEZQZ9cdFSBJL>o3fd0@Se(`8A%e=9M5Xv5J)DDZQIDD`g)X_nRS26w_S{9*#AXUYWOH#?oX(E%a zac5NFRE$2OR2jdC8pMVZ(_{zCXOLniP6l71XZ3>|s(iyqQ-W?uwWKLjz$l^_NyT_} z#AOhy7WfcuwL}BKpcz4_kf>KM_>(0rIKPQd3{`G#zj+FW8Qv_oYwJ%NV0)VT&#udR zVjs1>9ab@~hC<+kXj5d-$F=J((e*qgg(PhI9byb>#ZS(v}o33BOaSAvVx zLH?kfNHSK^2wrkY9$-+=HU^+SoKBNNB#3vISwY;H=IVi!x4dAZ6Jv z_-Qi&Y&_l|DEzJ_9L@DLQ?7>`cDJHWD)>{+m6LOmx9gQg2TaJPGJ;KnSc^r;#HAsX zlG(ysIKA~3h{vC=9qL!@+p4n~0@V8hi(Da=CrW<-d>>v7CaL;%fY@kL0QAeU%IC1M z7I1_Y^K9(PvI8@>0Cl-^O0@^2$RXaUE?-mli&RmDXY4Z=8_7X$( z%8r$DGO%)sfq^fPQ)e>T9}R3hrl-^b)OPH52yGcy696s=$m~BY8jy$EF+-ALnW5`{ z=ex2%I`_BnT#^l>i`61T=t3ZGIoQjy^XW#HcIQmzo>nc+YA>!zea=Ue(&|hFEi@-$6G*Re zbR{pPA65-SfSrEh+vAb(~mZo{;`f$MM^eE z(B<|YZ_~!zvq*-LgOBDvm=lJ9Lx-y15c#o~2<1HlyGIoJf}h041Mw6oH7v>OK#w_> z7uJqkhY%f-_SFXVI2~o z3&eR8VjYS7sG1htQ>ej;hql5G#GJn*mI5i^_&4{1OPRQy?C|*(b6M!{siV=zi}S?^ z-QJ{^ml%jV=z;QClcjlSvS^HnEJ@(+JfU{%=(N}py9N}6ASn>HmO1&0K1YnGw`p3Ve$%JP}{;h2RKnp#96 zc-Sjee~>6eZDdfh3jBa1Ip+gyt?W(>RhF$ z>;qmQGb|-j>R4$Cei1p#0)ewuWFUCRL4v#YQS?>BnNLraJnx`AxfXMV*I?v8B&=*A z+b}6Z<`D#jQp}x_DJsW3n6y}&z`{zXqn}Ve?>sPDV}sCE0HxF(NSv+KJiI0jH>hla zRwhV7m?^^IRa^g?UDD4*#a$8f*moZ4X1w*peqdAtC*GzP5cBE-kcxkfL^6$rB`jC2 zn8w%M5$k)xW*?`4jj9t%L(Jfku*^){D~MPan{(I>aN-^3JiraD$UbRXEWxBF(5yx4l&7urAZ@Q zK(I%ySDxJlvGr0XW9)D%#cGWLWCe*6$)m}>wzXzRHF}5otY{L)n+2HuYW61&MAh+m z^D_#mABOrq1&0pfqF#}(yYt4DAfm(k^X^R!eJa9 zH4=>M3DzQAVkxJBgPkcW^~ZIv3+hx1Akbyd4JzAW+3vTBcBWGsr<5dj9Rq@z3`O2+dJzOt6A$Sm#1i zxa|p}sb7(@2?~jq_>tj}p);}MitPERGGFl1k*;M`=&cjQqh@_f^YP6eYNd$DO@NQL zQ*km;#(6@nyUa$W6kk^(1xy4Zk3|N>hf?^sK~f#7tR6(hKB1u?Frw|rhD&; z7UIUv1t&dbu^!~^n=HHEnUwwq!LAkE?u0@C1G9+%17rFm*iOcl=B`X^Vw@su;_O@u zqTD><4D76|5)7geV&V*JoUA;|>};$Y5?tK>MZxuTU4h&U@84(z2#D61yve~#sE_10 zRqH+Pcm8NZCt1Z1WU47IP~`snc(G1gnDk(cHsxuF@OGjAgUS-#8(2Pux%K{};S)G9 zvlFxYeA7}=MKX6aJ|A0t>s{B0quFv9M+n;X{JTF(M@y&3smlAam6Pa@QM+p^v~yD( z5503ZB-G;#$XwXza0(uODk@ZNMZfNKRRCru8tqy}f!W$Dc}FREl^u_bbO1XKw#(Ko zhv+MXDW=6oF~L>Y$7(ICOUtKYb5$l%<23!lJEoyR8KKEW7YKX9DN;=0xbbrc!C0Jh z+{?;UlLgAIQz$(F{iB%O=|X-_^>(Y%DjE@^G0u~-@zaVEL(Crf(nS}}diPv^uN(%! zHd_9+G^h5_GtC2S4xcA)_8P|c#)h`hhNoAr+1S}#vCY^rD?#1d5viI~E1_3}&^Z(+ z)R6HY1`J8+NX!Z4LO7|-QHt4e)2QvD%E}_;ciQ_~fcH;F^l$p8e;rV64R~@H3K9aM za_(&)B;GHD{BdiD4STn&_4TT@Dk^E!?j)9)5=1&J-GKwTpv8RgnLl2OfZio_zpBc% zTI(#_qxn+%BU2XZQc#&9XzTkU;$3_ZtMJiCkH5Zr2Y7}BVryzojl-by3l#E#I5RbtbQ);XgM)o{jlj{fyHP_dc{S!o$J^w=DeH!gc8x<* zWd-57)(IK}xzLA3^KNog09rE_1Dn!joM6HYMnwch-c>!f4|rfr{<;MA3q9?$W%s># zib?x1a60S2W?V#7o_at%JL%5M_G_!|*4Qd~5dbE|j^&NRRyesqGpg{9KBv$LFRmy2 zhbr~~o%x1At=OK8#v*e}7VlIuXxP)$;VksQeIb(7&~1$?-n>y_zGu^IwYm3ZNmIYz zRn;|_3)$_}A?C=PGY@C)N2dl={P(Y0sj})fc6#jT`adj(?3Q}JE2nw;vrbYijtH99 zKe;rk3|&RcTkA7SmsKk8M>x7>XfHObq95IjRmQ}aV{Y**cn83^9uwmK=a2-N&#N6=3O&8j>rQ12 zn7V83%|j{BEst88A?834cxc`3bIx*8(7Kd^-@3(<=Sau@N=l{~j$-x`o(2~{jn3_> zxbB#u1|EB}j|*aN0H)V|7JpT&?C^hyIiHugI+8`5c)!8@%Q@9orJi}#K|Ck!3vS~G z54&*$0q0zYv!e#xFG{kMGJ@J-hTP()>G&K{cP0(g^dVTlc++osY&T*k91+Ja;->!k zhm^`yocFK9xfWanT#Br1EHqUjCCad6DkM*z92-BSFgP5{o0$=Hahi5~s7f?HxVRwB zwQ|UHT&aUCdEsWqv`%qP)CPKi#f^2#>4?^2hRrw>M>ZN|`)}6YhPmnXX?>EW7BuK8 z-z#>D0ZsTyO2>Dh&uGj6M6gs$fHMyFsC@bS`k2@BF8)hUOJhgJ3X;dyQ}q+~UiQTf zuqbF8d5+$tfl5mS5=7ZQl@j$Zsc)UBRlZ5LIg)+6n`QXd@npkJ%($Gcrbp=3;q6zWhmzXZh}(`S zUBKg$UQX|Js~6nlLqd&+=CwrkHEWg$#UQAm!Ab!<3&CJY2LNficJoU9{a5B*Z(xlu zXP!kM)?&k6jQw!)1u@f^(6yndm%+!H%~J?4L(`IR|6)`ksuV%PXGSKMhAZ-1ku z;Ij}$9Ousy&v+(xgg>>un||E`+Gs22eY-I!i>lFL=XCfPoz*)Jj{e}F^CSpQ&mEe< zNvp+ME`g&OlU={WM?3$sL6?E>mB#bEQ@>>XLjGZ0sSvg8Ve1QIqgB9Q`ZVqbz;Jlq zB#9nyy7jjCxH!MDLw(qBwE((mbZm(##iyrYP;|UwFPRHIkWj9W7B&jkE@r@vRK4&r z8fU4Id;zEgCkbPQCYh*_U+~1)I415#%|;dCbeb`jguhh_+_%Q-7zwl&cmWoENts%i zCbP@ycNubef7?7ux${)I{X&62vc+p(*1$G;^<<)ldsA9u%%^^L49j+7vYEf!7oLXe z%-IAq3?uq3L034R>xVhZ77U zD~oXR$|0s;p4m@>E-4@+ynD>Q*P+0)RL4mFHS%s;eH2?iiC?JVsNf9)X@YFqYsYU@ zM~XdUyXpFKwH4ku^3+$q6p<%Y2)^q{P--d5k+6F2#WW zmb=DQ)Si6k6x=G`BluN%q0%czUmNslcHlL?nA6y@H#3ge9~4WIiZ+OuT1a6O7mJf@ zExpIyVNuyrjr;Z0@x@_PYM8kxlq+?sG)ncjDUPmdh#T+drKSIS+7SSD!!Y{ z!YjMzsd1EO+U7+bJyRpSQ2V|FK_;R^-=(QlsyIf_=;Gf?8yKI%-PUt?{H*b+l$$mv zTipf)LJlJ*VwMUoHDcf%$0F6jB!Jm^Fe2cW+TtpZEM=vnk*|`_GYO9kQ4IbT?rzfd zeN|Nyh&;VYYy~^=Fu>hYYky615lOB_25>?ar-L(7?~5!BgQcUr2@V{fLe=2BLh=2{ zyHn619z+Exh92G_ETAy2krE-F+ixiN2n8GXw9Q0(IQ;qadJx*{_cuLo)leaFIT(?m zdIyd<4N}{^Ppd?RoZ!m(_kV0ZX5U?Qx<)iu#qps9N>&Of!s`KvYhmzX=DWT9KV{=g z7trGg900`8o{z9c#M6U;sH*aJ&i++IfmMxzE#5`Epm)4S|1SYsW z`+%No^E=h}-)&rCt`k2LvC*?_#M%?Jnq2SGMv<@elL!cU*F0eyf59SdJ~p)Q*ChFE z2PF`!x%`bpMHq%jKqv0QGC*S$_d`M_ZWZ?{W`&2RM)3~j*wy%6TyGj#tN?3jE?eav z8JQpuI}0i4cRv5TK_(b09}2Z7B1wtod_mi=&hyhKK@~$RNZrdPop8pnvGF5qmdM9d z3Tel`3zi-%qWiQDva003IFmLhu18_P zCFfTmNBf0`278{ZKE+H0TTGbf!BnhoD(eVv$GGQ{^n{-=z{dmLRdYK|w(d{@HUmRNg$lD>2hL{w=C+P{< zyEcAnE$R8aLves1tcn=QjR<3H!!9eai}|H#286#MrVDsU4D+>>Yo>F=W$!dyQG~lhB^?bZh8{M1 zSb?M(PDFuKSQ8UWe$okYduxbM@UO&Tzb>7cO`$pl8keBKl_kH)AMJFXOsMkkP=o=I zAEYkk+`pK=s^J|DJ1H6e*C`5}A1EKoVUvjO|;*njMt zjzSS`Gw4b))IwY(@hQ&+b`n4hLf-}8RnP|Ky#Nsn;H4or(pu-3q2)&uNQaAcEF60G zT>tz2P{sJ7TX2r{;;&f0CFsm9qaX6Mo_3e_oiVLZ<~5ZhA{3R(+Fvi?e)w|W67}eO zv+}O9y&f`r#JK|fyFjAQ0e;9DlF4}Dp!H6>cZiVNGH=n!cK>@v61x4J`fV#(&b*G2 z&-U?U7)zx%|415@cj%35sbGfLs<;1WsHJ@v#**w967XIB_)jP z{JN?W4N;%}GpdChAI(E}#W((WGv(JM_MJaL;2Rm3FCi8St)zyR5jG0g3PqoJC8Qhhx?-Zn|33w#xCFB}2R9o#gBS}pHv>D5BsT+(s3Z@A z7#AliGbgJ!Ckq$He+f!0eb?eP?6+@>xz+F_iD6rbL9twWUN+}B{1mE;`1|1*lKLdW z7w&g~)7Ud@)}0NVGE|MK2k8zo%K{IZMMd9ovjJUc`bXJ31nnwQ<*LU7{x6EDfE%bU zDGTzV;gA&k!%Ar8ND}-piTQ(`QF&+y;mju*XF6ktE=4-lbQ|23qkQfajFm*{&ecMi zr^ZFPd)XUf9jaoA`u3a^UbVne+zmYK-t(6#9o2)FTvXm(%^{J2ql!ug+k@=PmWXg2 z2lbbNQ@Q81Bzf?bR)S+U#T?0+o&NT<8b^2kYTmtA`y=wgPJgW5%lYb=8fl?V5JUCK))GfyVj4DL|1gr&QQI6`FS0H65B2H17$>kil%;ws!D zXr!l?^szGUXFE_w^^z1P>qbopekn*Hr_;mfsm}mW8=CEDvo)c*Wq$Za*{7(fmStP< z{)M25qL?sni4$PFv2Fn?YAnz_GlUnf;<20WZ&1Sq^no|A<2lTX8K6fL4`Y^xM_?ra zpC$|5Rce#LsiQz*mQ#^;CI$K~PI+r-4qJSE&t{v385v#r8t45h3nIw>lmTn|z<#3@ zQBEwhM0HKtXr8U#WwGy?d3VeoH#fI$8fCb;IZk`M>NE&+H4L=tF9Hk#?^b*KW(VW zI+__|g4(wA)t6J4)aQTQSN!}DkfGCYl)jN0{q*L(dK#d95!x2gihNGL0f5eqsl2)C z;95GWQa?qxpUFcFzbHkv(iF;ors!O3U@$=AnQ}^_U=b6oQ_DoBhX1GldrhtkRF1`0hFE*su= z@-XP^j6yo%%-YJXQq(`qy*9qdefEey;qB~~1pLG=+!DrJV+e?EbrFSlr_gP7-kDOE zUtC<+ilA-=SS=M~cj;01gOg`|cxR&z>IEmIBcw@W7ZV+kJbdVqd_1NcNm2Y5QvTu^ z53y^4rR+5h5v`9S6)b%Mg{} zv(>!lFhIAy<%4-x{2^y(a#x)jW7CNM_L9`#KUyvw|`BlQL`9)a|8+DFB zWs2fV?J~6zTX(8luL^5@yU8^Kr<( zA_Yr8r*qFIK!-Jlcly-dqu9e&UQ-^0GkPV+Ve?)R`7dM5;lr*C+5*zwN&A?gi+pNj z{Y?#mA_nJulX4kfql9WM7=0R&kuNa8v0Behm)kAvkm&|GSe&@EfUk3A42uAj3mN_f zZ|H~pB)jU#thl9fkb&x6hYp7=$&KNH2i%2Zi;MK&gc6~qZ&Dj&FX@M5IP$D~>761Ne=uvZ;7x9` zfh*)_!(e&Rx|kH;Rm-4A16!mdZ1kGgi)Y)e>dl-aqQzyt?6 zNl{GB!a!8BFaJmX8}4aG7yfzr@UrLi<! z@fh#dxMw`14-CZu=Z zO3?k`xg@f6MqeotHhEJ2nvM5xyYXNPyAjzrvWj2AYjKoTEm4IkYHtRD|4*7FG;i>g z1Og094(h*rXK(Ii{2$-tqK~?Y)2G0?~%#VEGTbBp6PE-e`jK?dPP^@?6Tdq zyGQy;$nrzXjm$3aTD2Vr1w@=COEX%XNsrfI3!q^bq%pFY1>nEG)!RsH9c&?L)L-d$yt88|Gl>qgaS6 zAe0GSsIpEFn{`ww8-8h-$V+Gv*7yR7057>*)r`fl>F)qh&Ak~AnV;3E$3^nt^yS&1 z!zK>-bA!&Ii{@a9U8}v{>tjrz`*kajvc#>2G2*4vHm2vxX-luJ;#QW{Mq^1B4~pv5 z%z_M;H_fn{b>>yf1fr|EyQ{A^XqGH#zes@Atxh*i9vyddK2RXV?3RlO`97<(+r^xv=zSi*T~(w+!D^z$-KIvqM!qTE7;B&q}PQIJK z+{R1>V+%HFz9-P1l<6_s#zxDj?5(Hnyw%HG&Lav1{*#}v%p^fz5O7%ZiS%BwRN`RZ zP-u}*a0;7na3n#(a^N9sRCp=mpB7Nmm!EG5lazw><738-p$mh7hon4wB1zCxgSKPg zhxb1LVEtph{~3W+*l8Hb)a4Tpw7oCzZ-PNA5^mEF7M@Rlu+ufsCmhNI0WF)QKjZ7? zxFp=(sQ=c%0u48nVI&v-2|&y4f<+Ss3(kOmvXo<{lKKREE(`MiF6;jXpB9~|f?-+; z6OWsPHX|2eoNzk=lAjg8MgKM=4ZtxKl92)T>2oVw5^f-aSJ=PkqY!q&85|V<=iE-P z{#A#5^3Tx8Cjk#>B%z`b{dE1>XJB|B5|Mt!2sAueHZ%(h`e!7~FbX@h=>GjT8jW<& zHhpAN)W4AN_{435Nc|g4&5cvXBo zz18Z3OSfsc;@~j>l3XX|#-B)Ig_<(imdNv0kM8rg@h|uf4n;^hOJtDgt-E?MGK?s>_#j*w~B?`HDGvCwhYH9qaCd{*t=rvU!;{3Ka95C@G6iYKMG0_<&Q1K(F*skM^Hj>(a>G zEa+7`)p_1wVoD~c&7+<^H=u6KW>@-R%WXCj{O3-L4%E@r&gXf(F|pqTOdm&_MhS|H_#&$ngJv1qF6kz^_oin>pv+=gTC9Z?A505?OLJ1 z&0~?=BwDS^UuISg2=>vRc)gm{9ZvxwCled;Nrf{|@ZZ=zd53S`s!rV9@3+CGO=PsH zx-81*PBd(u_vtZd#lpY09FaWrCZMJ`zFYMya5~9~B6T!m|J%Pr(c6EDn996DaTm6BbVKyoR|67XLL{+7G5xI z2T#`~TL`osKRLg33N<#na+^I2?4Qo}PzJVLPrJOBdybY+8&K`FuGL%JFu6&-`P`)d zn7SmWKy{v*>9It-I*fulwyYleZC&$NXYhPhx1DbhW9jcr#afMKf|NAEPH9HU(cRJ` z{0*WP>t$ZHx@ANz9eR(MF(rYQ?=F|Fo)fOBxk(9eL`=)M&fVvn9tkE)0qHm2n~Tkc zP7mf*)>jVPNb~$mA|{J3S(ED7zFTIB-Uq5$#caD790YvRHQSG%_4cpqkvKUSWa*rM zhs~xy?S0MHyS_m@Xhq#(>}@+LyG{l4(i1cK7%~bS(3Mx#q--|(-&T5-alS0wrFLZ9 zlRw>i#nwQh5HeTIyJ3$ZoRk&lY0vs()xX(^*}GS-e6jGTyF!*nb{QbC+FjR zcCdHs9^%Xyc7G+!lp9Y2BqZBMBqW``@(FHLk90ijt~$S&U21B2+H!Waxj}P-_qf@r z{-gvt`xJFG=^I+p&gG55n^MX0=A;>Jc~+XSf}|2O7i)j=5x;f&?d?~ZMN|(@5CIjF zL#c?!4BOr*${qE{$zc+H>N37J_gvs!w_3iFN%_6f@Z3Z;mXuadogTfG-0TBBTuZuo zjap&}?pWG)&Mzkn^E$p$#c$|8TfyZ842)g>5Sva^1bG*?-0<;OT$&z?EfXg!c?CL; z*&E3;4z2I>i0L&s;j#C{h7FR z{EcZHXx(w~`uF$ByUV+fo@+uX*3Lr$Dmebt6NQ# zgVtS=_tc}454*$pDCmHgX&tkg^rClyy2u&F3`gnHb&0WSeofi_x9JD7nnY0{cU{Ce z3=^6RDV04=`eoikH9I!O9-t3{Mb4gz2HAU}-h|ilORfoh#rJZ1zx#e=UqbQ-kat*1 zU~TsO#`HvMfM=W?i`8d~d-mbG;EQ3$bSsa}cfkW7^{D^!7K5SSA;hY~V1~lH`%#2v z_|jOKD?noHqs7hAqpM{Q3T_JHn{+*H*++B}J?(DNtu~^?*dYMfURU+Jt*gjwemPwG zW-Dd&#!><>9dQxh)kJG&o2S_QE{@g4=g_UnUPHNoQSE)vIse{ZGAWDC>7>PedCu=R z-`w|-+bd-;~pOCj%cEkA#l<=CM=ts5Y7ifBDJIlJFvz3u#df*D1OAokPm3uEBwGxws zoDc8mewHQPxU@FBN&6GW*~vzzF}uXRBsE|CV(71WamAVQ!$TYePvFD~R%>1lGhZ#qUL#ZZdfq(mk^)1wz^=-g< z_Ho&w3xjZ>K2)HE_I;-i_0CAC_te^md(Xkd{5vJ_#|p($;7E4ui}VLQy2wCD1Fy68mXqkK{B|-@b=sE27-Mal z8xrpC)nt@C{2oTfr9uIkIP^J8zL#wYelEX*XLUCJ@LY~QeB26n?>0*TeT>Qw1YYML zuU8cV7}t(6{7rg#?w_{|sgG>h{54S_R*hh@-rxTi9#m^PT2KS?FL4Gve!h>&NKFKH z64A>~%3uH4FWV2&N3{WL#RYa5Fmm6MweK$2t_^D&;qq|g`|D6pC^&78Va(M^2Xg?P@Pom!;Bb^f0QCYhGT% z-|foqR(n={OyJ7OqCy>fv5WI``XFtPToz5YdKn^ec%DRh8cT;61p=FLd6dqd(yw1( z1e@e(nG9Of<2a@qFdf#|v|4PeTfxrnHgcqDpzHi|T+`jUr{|`?-;8!%+6|_-p*pZ= zHm7PC0Xs6EM5FJ&GUqK6I26Pug9*;Jh5?6q{iL}8HZqEz#5(blSi@ym{C^s*k_*sA z=vv;wA;opzY(sf1A8dH#H0oNO3j`Rh8sDNkmlwdiy*`}H9!-^XakXztg4oVs75KHL zUUqnL1UFpY%X-Pk?_|HHZ}`ac-3q@RPku9ME@XRv!a?f>-J?m1xA4 ze7jx3U(#@^MCy(U_jg#Y>2O&7eLiJG%I9;eF>AhOC+P9S4X|uBz+vRm(yeaYu<8XI zR5uD53tn1cShuC(YIgMJMfr43}We zte|zuOPh)7VLrwIyAvZ>-*es}XLfFmEa7Z1CBSQ0J|~Mvz|PiMfulL@Y;mVYoYUpE z2WC;H)!LT|`*qyd5_*?JH9=RJ`0@j#a#Un(>Q?I^SXCF z&~oWfOG0pdDxsO@kz+7@V_*NR7pR^w^|+vYy|~Ae+U`R*4g299=(ft+snnqVGVd^Z zHP?hY#E5D6q6DJ5-0I%by&k_!cMm*&JXUd`Cib&&ODME6^@xcF5mByAQH3rsdGV{viU3PtAc|crZTXM)Twzcs{X?AxU z170oRudcr8GU>dY@0S%3=LPJI(QvmeFMA?Q-2}SDv%72UHQAc4S+pa2@F8|~yc*sP z+pp?ctzS)VNd~t8+XVK5aX-*E+~;e$pW+QL7aV$>CpNgGYB$V*@UuE)KU)1)>%4}@ zR<%bwzn zYrYx`e6i$FD+f$G_Vv8&KOW(Xd&b*#XXnhYcEm$VxGRQC|$?lup% zA9nm>T&7)FqNsCeF66MM$M0jx$alji_ZeA#%B#vcUh;dcPoxABK|)&Os!|?~3^Y^K zY|+6MxI8_(%O8}uf%mp9lP6p87S=C9pe2G;AUg0Oh^M31b<{#^KPjEa&UVS+#a1)p z<5i?g@(k^FB*mn2L5q%;Z(lWAmpZ#*py1Oh-P3EH z=J>M0mcnUebX}vXJ>N#RyJYUrB+r_HW5t5JW9Ot~_9yL=Y@MwuI*qwY`~Bolf^M1n zRQh&{7-KefUUI!S!M8Obuyt!N;@j&E^TOTTpqG-mBbD8bF{7%{Wa)ELnWnf$2eI;-?(Tt0fDgn6)d5=zFNe-uA2@R^?V@QQ> z->noYX{gced3*7^#gr(v)HHw=D6_q6@eb&RY&;l`;Yu$DI{0`t(T|R;ievL#G~IAa zJ>Mo>EI0zY`B(zX!p->$OUOtSL9=`alOL~p5h|JEqkOuz$v@*QBdO~ei3EDjYa7jC zo?)JbO9ssDBkvOeh5;$PAHn9dZjrWHkC5c-Vc2$^LFS*&?xA))@QaOsRirLOb@62C&$-6m9zuy zFxjVt_os~SV&@P3l;it2B;2l@%s8Lgee|2K(_zUD{6AdlCl2_d{-1U?_^duLAuIl? z3$=gZ))`|ZKDGPxXWsF)_Ja6_WB9~*7}I}N0unWYw*Pz|!2E}E_{6m$ntqn3g1bJa zHu#eJuiE7DDe&6$@nZf>jZMORGxrzjA5QlZ_kZA$h0QN!V;QW2W2G&Wf0!Mr%lb6G zgKVXn0#3ZbSV0iX(Q8XK%QB;)F-EAPEl_z zixKK>U!p)g)0_^)XE0unHOs0)$abewmntI@s6?AtA~W`(F`F|J)z7Ko4mktoTFZzHaa<<5#Bvz3|qr zv^4z1Wba;;EZp0)XvLbO;+h|weiB*2v80kQ0t zniU7hQ6Zvwo?)FYVPr05D9X!xWGrMLkSHnpc)x#UB7bAn%rJH# z1Kb~__R*SzEs}J@=vg39LE=>$iN&2t3Lc#SmDUASMcYV5yA9ma#*u^7Zy}B1XG_;i z8+qkYlO?R=sj#(4gJ?^Ps^n^_|Nzp)^U4f4)H!EOzaW1 znGK&(Vy+HhvwE{*Hw8>X-ZwZuT8=^csrp6HIfIQKlhLo#P8nEPZD1Ja8&`~31k(C?L(j|SvKs=SKuY!V-s%6bO zaXWaA`i(Ma#xN@?4w^}S0Me%;nJ9A-CCZ?~Pz{w%EkJHr11M#gcTse2`Ou({J>y4!tDmJhc#@#~WjMlmUSk|3@@N0iZC_nlQgyld{8U?^Dp@ zzoaks#?$EWgT7l&@zh}TDPQuAr~`*z@`DEHlPiMU@LO$?7XJMHy^$s`ZvtvztbDTz zjhm?Iba9xN-I-Uw>6%wh$VoEa3LRB{q#%SH5|}aohxTQc_K7(o63Q%cm_!5RZew z@I0Z@tb68{WjHt8d{*iQDgeRHI~lrTnW*!X7Vo?-g(}A-EJ_chbv#uCFTFaxiN{Pe zzSnZ7G-@`g*==C_P#z%nNxp}$uS{Uvp%aKK=!C4GZibPax9x!8(G6^OKNt;|HIKWX zo#`tV5Cu+N@#WPYar{NZ&oZb?>`G^>`Opo!T*d3=0XtNNW)A(G|ORW|E-`iVcr&F_OJ!I75VOALAu02rVR^&fcm#?%CS& z#Pix0o>p3tAdaomc>7q+MO&eg9k#Y+P{qcb-rU&df8xWI^6Q>B1+^*RCjo2I9FoL$ zP4d2oM2I2dSJfhBwi+A}>@q_*KH^%-g3Ig5)C|PORL{Sr{B34Q8s5SeM_Q(ZI?vAn zTK!|nm%kO?k4l!Wblpk2?wKymJx<${3&^H>Yw4({x*Paf2c3X_0jBG?+Sz7s3F$hpq#;bC=asg?v+O6khZe6$c zv7NQF@KWR!7|mueI-T!LPBlv-<(~oc?D-pF+Cz1vK>~2!L1k^*H_6-M9Zi%mH@Ok^ zrR=Dc$#s#Dwj8hg#^IxrynVQtvHRT-$2CQzJB73Do+C=ILyoWYqrfJ!7IYji+XVBg z8Tgu}@Jl{R!oyP%_`38!(y8HKdxa$M*-N-{;0B&I92X=VTlF@%-bDOzEJqFjgNmx?DIX zPHUdGbfcV_5}f(CP2t4x!MD!Upym9iAk6hthjc(h}HR z23=gP&-ByVA+Ov+0uQ^Z!GR7jhk<7mpf&Q#7GILn6vohMLMdJJwJyTg2Gx4J@lPH{ zzqRIXHpU0qTgY#mTs-yHMRf*(=N0Gfs(p;;Y%rCP7Ea4-p)_i}Ol&-cz3&PcQg$oY zMM9Ld8}hD6Sp)VsUbti?1LWuadNo%)eYZbj>aBrZqq0A^Z_#Pa6&a{F;mPSmQRYiq zu!Xgq4&mK0vYlSE%_@;eua!~dEaK5G=r^~mUM=u>Iiwk_xK*P^Y&ln|CbfUz0l9tS zLrbmap9gDx>)61zSu7HHsIO^PJ*w=te&PG(p66l%%0%*DtOi9}`ADWeQEqVAz0J#m zDsr-lRO>tDIcq`M!GlrMIdktQXRGF`R@I*^vO`ILr?O>LSvC7cfpsY?L`A~#z#@UM zm4JlQ@|;^W{W4lL_-Q%M{r5b=bCQVaA$Q&gWmm2usWMD|VA+I1Z^2ek^K5f}R*uvG zH}bi=0(a{{)Y8}Giyxy3ojsQ=oVnW7|Es+#4Qgu3){0DC0ku(35D`&OhD1~bnP)^q z5Kx8?RAw%dKnOBlz3Ex@+&IqGrL%Uk)bfppe=oU5?<<`mzuZN?j za^Qu8mpE)XcT&eE{ORl)j>Iz3G&ZOJ&T& zHG!b2gA=dAj~d`aJ`a%VGd48@iSlK>uYy1p_&TPfp=k7!0*5NT^%UgtMn~?N`!SwK z=yTZu#gU=DB3uv|OGK4z(8h-FX`M(i}J zwOB)&aBm6{kJ2ZfA)znyqg5SrtP8`{yZjz=Rg6Ymnyzy09GV4QIwiZfgKO;W3xacd zypXE7w?sQ9uU6OCfAE1p$#dlat4ESY^2;pagnCoIK-wpUDB6+}q>r_xI`wP;qxSM> zJK@;TX8s--MO;vUtXlYhwny)0MM&(Gmg5TYqSv0OG^8zuKsZliR7V-S(H3SUTihO| znJ*)y(xqwNpTloEqDS1q9FCGjzf5tb^j!Z~B{gxmY$Gyt5?NERnthwm1HXN6z)HTr zX=xC2*W2KSGCHhg$_nuScl1kqF zW0T+)wSL-LT~>jdSJc}^QUx|#ep!$%N3VwjUd~JhLh~D6?L6$$Uu}@m*drz(J~x4U zpg)9>MY}0fQPnZG@Tu?w~` zS92|0HH@j8%#U0dwla#gQZ9RNpfEiJTU9`F3|@V=q^sBKihk1+l~g)^2Mv86m3a3O z>uMqajvywSc&DZ61w#uR>I*YB(%Lr`P;*$<=B7{PAG)_-AvYM>;_ zn((elkJ@G#*WL8EeA%T-gYv!2DLwmMl+k4twd=$H>wC`SP>O4g`UdftQuu;BFBcH% z>!qoKoZZ~Y1jJQthA~Kl02;3rhSk$MKWv6+(W_R>67|I}k9c{R_PV6#TpZM9w+e`> z+knuUXUBs_50=$FQAjWVAb5Sr4iJcZB%8kcC*ZJYkNYWf#tW#!B8z7r>}1(uF&sSDk?a|heXCvajYpx(yD#*m66Z?iTs zd>aYIJ`Uo%f@0^S;}4UsqPOq&Dmnl0a6D|KvSbwBv>`}c7|d>)j!c={SZwQ7t!5(? zAQ(rXvFJ8rw%{o>U8JPyU8I;+OJ!tu?JOlHfjQO`%m;a0i4;?GPxZglK|~Vh(m0sU zE6dmj-%A)6_m~a1z`>z0s4_xTpy zkqTQVEyCJ5BZ9eA-E9kQv5fcsV04v~-L{$I81PjY>+XlYsjjIuKbJB0q(kScNL4k4 z<=_0Ri)>;Yu~Ry@9F&k)c@V$$Eg@*Gi_Fno=+6VYAn|vrnpr)bxKIW`#<;pjBc$+V zkv5c$_n-D;;JjK%^H7Ltfr|QDb(@8Fy99LWgP=xTeRK6jxiBh@lSLyms$^+}HH< zUQAS+f_;n4bL}7e%Nc`EPRYY_ zY(>CMXJw=4O>YZUlZl5@D?jhdv_+ruH!qN5lj>3;zJ19Et_+FWA~8Z-WpQqDeZ@o` z%?n?1+)LRMwlHq@`j&H};d+pDoq}D>C4Yko+iHY; zoqMl#(HKMpXU-PA7h!5JKkmsos6NeNg)woQZTsB3yv~t@!bcQSX5WXR=PJu}S0dNi z6J9O8Mr$dGZ6KrkJv~!Lr(c}f_F&P&ZEzOvS|Y_+NCv^`Av3XuwKHX)1Bt@2#sHHaiaix==-or7 zW?uA9+SaR420l?EIeHsU@b#W;+uHDV9WG5V0asR3d{ypOqU2Y7m=G%yiU)!8H z;AXomja5=Rq*SAGT3}vkXybV$WvN4^Au}thGA|J+;uR}#4Y}<(p86p`LXxvh3ZJLQ zS0hI66)CXEjYX4>IySHv&Ah6iZ|}UTvLvUsaGuZlMpmm(^xU`4GX0Vq@L5?zHji)6 zX#6TA*hgBr(xe%WsP4G!kAL6rvI=>NMO&7L9N!t@lMJ(4_~9OH+kwZuHesvyZ%&y{ z_^D4wdg1W31@FA;>?ju#Y{(;zmv)YDz}`L`;a4}3(e zEXO)v_4rPofh=L^b(lxSZ_GbSr)=85K7KC@CuL1f2YA39y8iLxDAs#%AWu}{$%j~A z&oLvV3xK8-X-AfryXVp21O}soq|u;ksPTf*BVTRoTM)qV!nVJOWH5hUZ6sq_qJs+i za;}6B?1Pz9F@oC~g6=l+F=nFiGj{ndlIfq~Yu=pNPOsM9pj`?4l4kPj8a-4?DpO_#`1Oym0|djO{0p>qnJURC+R1r<0z~NQQN{ zr?Ts@5?RU*CsT_3;26HiL_#78P+UiQdcV){)E_C$~u|HuH=-WzdglTzB<0 zMP9`G`t=>sN$_i`29qjlB<0Lj^R*rmavEFfmQMMRMj_6zRS8EVvM|)c(Z7a6>3T95 z2#Y0mR-$Z#ikKS}`D#=ImZG&|2osvenn;wzG+Wful_R^JdKP)nHv%x6O?TxfdL@8yw3my`5t39NAOR`IAw2uyl6ZAyFd})}fpt zA_Kktnu7=$)Pi8>McIa6W_Em&gl>EG8kJbRni~`LZs_}Yvl8XE&j<14 zD)3*2N{o_QG#^YZ`18dttd#3C$4kZXneg3L7(;1{QG`a^Y9Bhi+a{9kM_c+RKE#%E z`sPgsEPC-J^}!oX>-H$yc}{p)i1dlC{K0l4Uas;0Fr9?~Z|(pPdYAq507SsL9gO?P z(n-Jxc}#j8-_PA+2b5%IzkgT)@b*`L0>NMtPL7K|^8-+>>FRXB9@Q=W2NjR&o+f`P zk^W705Wu!+&EBfuKV#X&6){))G}#uE>?awswYpyPxw$DtoBn$gXnQJuQ0Xr*R>$u@ ztFw`x^=#J8zarbx5J#BO*RiY?oms-usZT?umhW1ms8jfx=NEMnK^G<~Pp&(2JM#nB zwFAkfsyAoQ4EIC;M1;FFd%paeS7S@J5Ir;$^`Zuv?nhr`Xh75Z{SG*1hxA4nPilww z*=pCWBu+d+ak1UQ+}=d7?8Dgk5lY(fMNkk%Iu&TP_Q`f^p5a>!~4a?&jC;c^V-!i-0}ti zG+U*^QEtiIvIS{^TU-kX2Hl`}cZNW2+kK3HB*qBlog!b=Y7Bm)Sq)R~N^cUmFZpJL zf`BisS_Q*V0;u_T0;ppIV-{e1v?oYFa-77{l_SWE|-#a!_q#JpcchZ&kxV7az ziY=O$pTHg9g71_STxfe4E1~JEdnR)qTg|`}C&b0ybo2}WVoQGx)QK+usE^F6L?Dq6 z-~SkAesP%}sC)tYJoX0enP+cO?EMORo?_2G?yU-Yi{@Uauoocx=Z1wboWn^5p6UQG z0QW8zz#m;f!#}$%b&`jQvZvT Date: Wed, 26 May 2021 11:06:59 -0700 Subject: [PATCH 141/404] Fixes naming problem by converting masterSymbol name to snakeCase --- lib/generation/generators/symbols/pb_instancesym_gen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 48220fda..b508970d 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -89,7 +89,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { return 'Container(/** This Symbol was not found **/)});'; } - var symName = masterSymbol.name; + var symName = masterSymbol.name.snakeCase; if (symName == null) { log.error(' Could not find master name on: $masterSymbol'); return 'Container(/** This Symbol was not found **/)});'; From 8736989de4c713386d3e42be57dad3560bc25d02 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 26 May 2021 16:42:27 -0600 Subject: [PATCH 142/404] Replace dartfmt for dart format command --- .../flutter_project_builder/flutter_project_builder.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index ce766e37..0e51c521 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -154,9 +154,9 @@ class FlutterProjectBuilder { log.info( Process.runSync( - 'dartfmt', + 'dart', [ - '-w', + 'format', '${pathToFlutterProject}bin', '${pathToFlutterProject}lib', '${pathToFlutterProject}test' From 22238c8240f9c67a1e6016ddf1634b04bda8089a Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Thu, 27 May 2021 00:06:17 -0600 Subject: [PATCH 143/404] Refactored the PBProject into making the project name and project path un-modifiable throught the generation. --- lib/controllers/controller.dart | 19 +++--------- lib/controllers/interpret.dart | 6 ++-- .../flutter_project_builder.dart | 29 +++++++++---------- .../commands/write_symbol_command.dart | 2 +- .../helpers/pb_project.dart | 6 ++-- test/lib/controllers/interpret_test.dart | 3 +- .../services/interpret_test.dart | 5 ++-- .../output_services/project_builder_test.dart | 4 +-- 8 files changed, 30 insertions(+), 44 deletions(-) diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index d3ce3982..80fc30e7 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -1,8 +1,6 @@ import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_traversal_adapter_writer.dart'; -import 'package:parabeac_core/generation/pre-generation/pre_generation_service.dart'; import 'package:parabeac_core/input/helper/asset_processing_service.dart'; import 'package:parabeac_core/input/helper/azure_asset_service.dart'; import 'package:parabeac_core/input/helper/design_project.dart'; @@ -10,6 +8,7 @@ import 'package:quick_log/quick_log.dart'; import 'dart:convert'; import 'dart:io'; import 'main_info.dart'; +import 'package:path/path.dart' as p; abstract class Controller { ///SERVICE @@ -33,21 +32,11 @@ abstract class Controller { Interpret().init(projectPath); - var pbProject = await Interpret().interpretAndOptimize(designProject); - - await PreGenerationService( - projectName: projectPath, - mainTree: pbProject, - pageWriter: PBTraversalAdapterWriter(), - ).convertToFlutterProject(); - - //Making the data immutable for writing into the file - pbProject.forest.forEach((tree) => tree.data.lockData()); + var pbProject = await Interpret().interpretAndOptimize( + designProject, p.basenameWithoutExtension(projectPath), projectPath); var fpb = FlutterProjectBuilder( - projectName: projectPath, - mainTree: pbProject, - pageWriter: PBFlutterWriter()); + project: pbProject, pageWriter: PBFlutterWriter()); await fpb.convertToFlutterProject(); } diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index b4f08999..e81ce95c 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -42,13 +42,13 @@ class Interpret { void init(String projectName) { log = Logger(runtimeType.toString()); - this.projectName = projectName; _interpret._pbSymbolLinkerService = PBSymbolLinkerService(); _interpret._pbPrototypeLinkerService = PBPrototypeLinkerService(); } - Future interpretAndOptimize(DesignProject tree) async { - _pb_project = PBProject(projectName, tree.sharedStyles); + Future interpretAndOptimize( + DesignProject tree, String projectName, String projectPath) async { + _pb_project = PBProject(projectName, projectPath, tree.sharedStyles); ///3rd Party Symbols if (tree.miscPages != null) { diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index b8fbde97..ffd8c202 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -2,6 +2,8 @@ import 'dart:convert'; import 'dart:io'; import 'package:archive/archive.dart'; import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; @@ -16,8 +18,7 @@ import 'package:quick_log/quick_log.dart'; String pathToFlutterProject = '${MainInfo().outputPath}/temp/'; class FlutterProjectBuilder { - String projectName; - PBProject mainTree; + PBProject project; var log = Logger('Project Builder'); @@ -39,21 +40,19 @@ class FlutterProjectBuilder { PBPageWriter pageWriter; - FlutterProjectBuilder({this.projectName, this.mainTree, this.pageWriter}) { - pathToFlutterProject = '$projectName/'; + FlutterProjectBuilder({this.project, this.pageWriter}) { generationConfiguration = configurations[MainInfo() .configurations['state-management'] .toString() .toLowerCase()] ?? DEFAULT_CONFIGURATION; generationConfiguration.pageWriter = pageWriter; - mainTree.projectName = projectName; - mainTree.projectAbsPath = pathToFlutterProject; } Future convertToFlutterProject({List rawImages}) async { try { - var createResult = Process.runSync('flutter', ['create', '$projectName'], + var createResult = Process.runSync( + 'flutter', ['create', '${project.projectName}'], workingDirectory: MainInfo().outputPath); if (createResult.stderr != null && createResult.stderr.isNotEmpty) { log.error(createResult.stderr); @@ -105,8 +104,8 @@ class FlutterProjectBuilder { } // generate shared Styles if any found - if (mainTree.sharedStyles != null && - mainTree.sharedStyles.isNotEmpty && + if (project.sharedStyles != null && + project.sharedStyles.isNotEmpty && MainInfo().exportStyles) { try { Directory('${pathToFlutterProject}lib/document/') @@ -114,11 +113,11 @@ class FlutterProjectBuilder { var s = File('${pathToFlutterProject}lib/document/shared_props.g.dart') .openWrite(mode: FileMode.write, encoding: utf8); - s.write('''import 'dart:ui'; - import 'package:flutter/material.dart'; - + s.write('''${FlutterImport('dart:ui', null)} + ${FlutterImport('flutter/material.dart', null)} + '''); - for (var sharedStyle in mainTree.sharedStyles) { + for (var sharedStyle in project.sharedStyles) { s.write(sharedStyle.generate() + '\n'); } await s.close(); @@ -128,9 +127,9 @@ class FlutterProjectBuilder { } await Future.wait(PBStateManagementLinker().stateQueue, eagerError: true); - await generationConfiguration.generateProject(mainTree); + await generationConfiguration.generateProject(project); await generationConfiguration - .generatePlatformAndOrientationInstance(mainTree); + .generatePlatformAndOrientationInstance(project); var l = File('${pathToFlutterProject}lib/main.dart').readAsLinesSync(); var s = File('${pathToFlutterProject}lib/main.dart') diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 0f627a26..54009fab 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure /// Command that writes a `symbol` to the project. class WriteSymbolCommand extends NodeFileStructureCommand { String name; - final String SYMBOL_PATH = 'lib/widgets'; + static final String SYMBOL_PATH = 'lib/widgets'; String relativePath; WriteSymbolCommand(String UUID, this.name, String code, {this.relativePath}) diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index fe62a5b9..3a9743bf 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -4,8 +4,8 @@ import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; class PBProject { - String projectName; - String projectAbsPath; + final String projectName; + final String projectAbsPath; List forest = []; List sharedStyles = []; FileStructureStrategy _fileStructureStrategy; @@ -20,7 +20,7 @@ class PBProject { FileStructureStrategy get fileStructureStrategy => _fileStructureStrategy; - PBProject(this.projectName, this.sharedStyles, + PBProject(this.projectName, this.projectAbsPath, this.sharedStyles, {FileStructureStrategy fileStructureStrategy}) { _genProjectData = PBGenerationProjectData(); _fileStructureStrategy = fileStructureStrategy; diff --git a/test/lib/controllers/interpret_test.dart b/test/lib/controllers/interpret_test.dart index 92503384..dc42972f 100644 --- a/test/lib/controllers/interpret_test.dart +++ b/test/lib/controllers/interpret_test.dart @@ -16,7 +16,8 @@ void main() { }); test('Should return a PBIntermediateTree from a SketchNodeTree', () { - var intermediateTree = interpret.interpretAndOptimize(MockSketchProject()); + var intermediateTree = + interpret.interpretAndOptimize(MockSketchProject(), '', ''); expect(intermediateTree, isNotNull); }); diff --git a/test/lib/interpret_and_optimize/services/interpret_test.dart b/test/lib/interpret_and_optimize/services/interpret_test.dart index 7297cf80..3af8271e 100644 --- a/test/lib/interpret_and_optimize/services/interpret_test.dart +++ b/test/lib/interpret_and_optimize/services/interpret_test.dart @@ -122,9 +122,8 @@ void main() { )); }); test('', () async { - var mainTree = await Interpret().interpretAndOptimize( - project, - ); + var mainTree = await Interpret() + .interpretAndOptimize(project, 'projectName', 'projectPath'); expect(mainTree != null, true); expect(mainTree is PBProject, true); expect(mainTree.forest.first.rootNode is InheritedScaffold, true); diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index b6e7faf5..94606360 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -105,9 +105,7 @@ void main() { when(project.fileStructureStrategy).thenReturn(fss); projectBuilder = FlutterProjectBuilder( - projectName: outputPath, - mainTree: project, - pageWriter: PBFlutterWriter()); + project: project, pageWriter: PBFlutterWriter()); }); test( '', From ab507781114b7001a9c67d2510e0d11c2e495427 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Thu, 27 May 2021 00:16:14 -0600 Subject: [PATCH 144/404] Made an imports class that takes care of the formatting once converted to string and enforces absolute paths with the package structure. Finally, changed manual path modifications to using path package. --- .../generators/import_generator.dart | 81 ++++++++ .../state_management/bloc_middleware.dart | 5 +- .../state_management/provider_middleware.dart | 13 +- .../state_management/riverpod_middleware.dart | 4 +- .../generators/pb_flutter_generator.dart | 2 +- .../symbols/pb_instancesym_gen.dart | 5 +- .../util/pb_generation_view_data.dart | 9 +- .../commands/export_platform_command.dart | 2 +- .../file_structure_strategy_collector.dart | 51 +++++ .../pb_file_structure_strategy.dart | 59 +----- .../provider_file_structure_strategy.dart | 9 +- .../pb_generation_configuration.dart | 195 +++++++++++------- ...platform_orientation_generation_mixin.dart | 4 +- .../provider_generation_configuration.dart | 9 +- .../riverpod_generation_configuration.dart | 3 +- .../visual-widgets/pb_text_gen.dart | 3 +- .../generators/writers/pb_flutter_writer.dart | 3 +- .../pre_generation_service.dart | 27 --- 18 files changed, 304 insertions(+), 180 deletions(-) create mode 100644 lib/generation/generators/import_generator.dart create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart delete mode 100644 lib/generation/pre-generation/pre_generation_service.dart diff --git a/lib/generation/generators/import_generator.dart b/lib/generation/generators/import_generator.dart new file mode 100644 index 00000000..89614cd2 --- /dev/null +++ b/lib/generation/generators/import_generator.dart @@ -0,0 +1,81 @@ +import 'dart:math'; + +import 'package:path/path.dart' as p; + +class FlutterImport { + /// Where the source code starts. + static final String srcPathDelimiter = 'lib'; + + /// The [path] is the relative or absolue [path] of where the import is + /// pointing to. + /// + /// For example, one of the imports for this file is `import 'package:path/path.dart' as p;`, + /// the path would be `/path.dart`. Or in the case that is relative, it would be the entire + /// content of the import. + final String path; + + /// The [package] is the actual package where the [FlutterImport] comes from. + /// + /// For example `import 'package:path/path.dart' as p;`, the package would be `path`, + /// without include the `package:` or `path.dart` section. Relative [path] are going + /// to contain this field `null` + final String package; + + FlutterImport(this.path, [this.package]); + + /// Adds the extra syntax that comes when generating an import. + /// + /// if [isPackage] is `true`, is going to include the extra syntax for + /// packages. If the [content] was not provided, then its going to return an + /// empty string. + static String importFormat(String content, + {bool isPackage = false, bool newLine = true}) { + if (content != null) { + return 'import \'${isPackage ? 'package:' : ''}$content\';${newLine ? '\n' : ''}'; + } + return ''; + } + + /// Formats the [absPath] to eliminate the path that are not within the project, + /// this is to format it in the following manner: `package:`+[packageName]+`path` + static String absImportFormat( + String packageName, + String absPath, + ) { + if (absPath.contains(packageName)) { + var components = p.split(absPath); + + /// We are going to cut off the furthest into the [absPath] + /// + /// either into the [packageName] or where the source code is, the [srcPathDelimiter] + var delimiter = max(components.indexOf(srcPathDelimiter), + components.indexOf(packageName)); + if (delimiter < 0) { + return ''; + } + return importFormat( + p.join(packageName, + p.joinAll(components.getRange(++delimiter, components.length))), + isPackage: true); + } + return importFormat(absPath); + } + + @override + String toString() { + return package == null + ? importFormat(path) + : absImportFormat(package, p.join(package, path)); + } + + @override + int get hashCode => path.hashCode; + + @override + bool operator ==(Object import) { + if (import is FlutterImport) { + return import.hashCode == hashCode; + } + return false; + } +} diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 8b7f481b..5acbc4c1 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -21,7 +22,7 @@ class BLoCMiddleware extends Middleware { var managerData = node.managerData; node.currentContext.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport('package:flutter_bloc/flutter_bloc.dart'); + managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); var fileStrategy = node.currentContext.project.fileStructureStrategy as FlutterFileStructureStrategy; @@ -84,7 +85,7 @@ class BLoCMiddleware extends Middleware { ); /// Creates bloc page - managerData.addImport('package:meta/meta.dart'); + managerData.addImport(FlutterImport('meta.dart', 'meta')); await fileStrategy.generatePage( _createBlocPage( parentState, diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 445761b5..7ca33f55 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -1,9 +1,11 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; @@ -12,6 +14,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.d import 'package:recase/recase.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:path/path.dart' as p; import '../../pb_flutter_generator.dart'; @@ -31,7 +34,7 @@ class ProviderMiddleware extends Middleware { if (node is PBSharedInstanceIntermediateNode) { node.currentContext.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport('package:provider/provider.dart'); + managerData.addImport(FlutterImport('provider.dart', 'provider')); watcherName = getVariableName(node.name.snakeCase + '_notifier'); var widgetName = node.functionCallName.camelCase; var watcher; @@ -85,7 +88,7 @@ class ProviderMiddleware extends Middleware { // Generate model's imports var modelGenerator = PBFlutterGenerator(ImportHelper(), data: PBGenerationViewData() - ..addImport('package:flutter/material.dart')); + ..addImport(FlutterImport('material.dart', 'flutter'))); // Write model class for current node var code = MiddlewareUtils.generateModelChangeNotifier( watcherName, modelGenerator, node); @@ -94,7 +97,7 @@ class ProviderMiddleware extends Middleware { // Generate default node's view page await fileStrategy.generatePage( generationManager.generate(node), - '$parentDirectory/${node.name.snakeCase}', + p.join(parentDirectory, node.name.snakeCase), args: 'VIEW', ); @@ -102,7 +105,7 @@ class ProviderMiddleware extends Middleware { node.auxiliaryData?.stateGraph?.states?.forEach((state) async { await fileStrategy.generatePage( generationManager.generate(state.variation.node), - '$parentDirectory/${state.variation.node.name.snakeCase}', + p.join(parentDirectory, state.variation.node.name.snakeCase), args: 'VIEW', ); }); @@ -117,7 +120,7 @@ class ProviderMiddleware extends Middleware { PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); var import = generateModelPath ? '${fileStrategy.RELATIVE_MODEL_PATH}${getName(symbolMaster.name).snakeCase}.dart' - : '${fileStrategy.RELATIVE_VIEW_PATH}${getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; + : '${FileStructureStrategy.RELATIVE_VIEW_PATH}${getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; return fileStrategy.GENERATED_PROJECT_PATH + import; } } diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 8984811e..3ee9afab 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -27,7 +28,8 @@ class RiverpodMiddleware extends Middleware { if (node is PBSharedInstanceIntermediateNode) { node.currentContext.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport('package:flutter_riverpod/flutter_riverpod.dart'); + managerData.addImport( + FlutterImport('flutter_riverpod.dart', 'flutter_riverpod')); watcherName = getVariableName(node.functionCallName.snakeCase); var watcher = PBVariable(watcherName + '_provider', 'final ', true, 'ChangeNotifierProvider((ref) => ${getName(node.functionCallName).pascalCase}())'); diff --git a/lib/generation/generators/pb_flutter_generator.dart b/lib/generation/generators/pb_flutter_generator.dart index 065a7146..53769634 100644 --- a/lib/generation/generators/pb_flutter_generator.dart +++ b/lib/generation/generators/pb_flutter_generator.dart @@ -77,7 +77,7 @@ class PBFlutterGenerator extends PBGenerationManager { var buffer = StringBuffer(); var it = data.imports; while (it.moveNext()) { - buffer.write('import \'${it.current}\';\n'); + buffer.write(it.current.toString()); } return buffer.toString(); } diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index fbd197fc..aaa447e3 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; @@ -61,8 +62,8 @@ class PBSymbolInstanceGenerator extends PBGenerator { break; case TextStyle: // hack to include import - source.currentContext.tree.data.addImport( - 'package:${MainInfo().projectName}/document/shared_props.g.dart'); + source.currentContext.tree.data.addImport(FlutterImport( + '/document/shared_props.g.dart', MainInfo().projectName)); buffer.write( '${param.name}: ${SharedStyle_UUIDToName[param.value] ?? "TextStyle()"},'); break; diff --git a/lib/generation/generators/util/pb_generation_view_data.dart b/lib/generation/generators/util/pb_generation_view_data.dart index 02464c53..b6ac1515 100644 --- a/lib/generation/generators/util/pb_generation_view_data.dart +++ b/lib/generation/generators/util/pb_generation_view_data.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; @@ -6,7 +7,7 @@ class PBGenerationViewData { final Map _globalVariables = {}; final Map _constructorVariables = {}; final Map _methodVariables = {}; - final Set _imports = {}; + final Set _imports = {}; final Set _toDispose = {}; bool _isDataLocked = false; @@ -26,7 +27,7 @@ class PBGenerationViewData { Iterator get methodVariables => _methodVariables.values.iterator; ///Imports for the current page - Iterator get imports => _imports.iterator; + Iterator get imports => _imports.iterator; String get methodVariableStr { var buffer = StringBuffer(); @@ -50,8 +51,8 @@ class PBGenerationViewData { } } - void addImport(String import) { - if (!_isDataLocked && import != null && import.isNotEmpty) { + void addImport(FlutterImport import) { + if (!_isDataLocked && import != null) { _imports.add(import); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index 4e317e2e..a0ab583b 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -8,7 +8,7 @@ class ExportPlatformCommand extends NodeFileStructureCommand { PLATFORM platform; String fileName; String folderName; - final String WIDGET_PATH = 'lib/screens'; + static final String WIDGET_PATH = 'lib/screens'; ExportPlatformCommand( String UUID, diff --git a/lib/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart b/lib/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart new file mode 100644 index 00000000..6b9f8d93 --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart @@ -0,0 +1,51 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; + +/// The [DryRunFileStructureStrategy] is going to mimick a real [FileStructureStrategy], however, its not going to modify the FileSystem. +/// +/// The main use of this class is to analyze the final location of all the [PBIntermediateTree]s given a set of +/// [FileStructureCommand]s that are going to execute. The only use of this class right now if by the [ImportHelper], +/// where we are going to record the final import of all the [PBIntermediateTree]s before actually creating the files. +/// Keep in mind that most of the methods in the [DryRunFileStructureStrategy] are going to do nothing other than +/// notify the [FileWriterObserver]s that new files are being created. +class DryRunFileStructureStrategy extends FileStructureStrategy { + List dryRunCommands; + DryRunFileStructureStrategy(String GENERATED_PROJECT_PATH, + PBPageWriter pageWriter, PBProject pbProject) + : super(GENERATED_PROJECT_PATH, pageWriter, pbProject) { + dryRunCommands = []; + } + + @override + Future setUpDirectories(); + + @override + Future generatePage(String code, String fileName, {args}); + + @override + void writeDataToFile(String data, String directory, String name, + {String UUID}) { + var file = getFile(directory, name); + _notifyObsevers(file.path, UUID); + } + + @override + void appendDataToFile(modFile, String directory, String name, + {String UUID, bool createFileIfNotFound = true}) { + var file = getFile(directory, name); + if (!file.existsSync() && createFileIfNotFound) { + _notifyObsevers(file.path, UUID); + } + } + + @override + void commandCreated(FileStructureCommand command) { + dryRunCommands.add(command); + super.commandCreated(command); + } + + void _notifyObsevers(String path, String UUID) => + fileObservers.forEach((observer) => observer.fileCreated(path, UUID)); +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index bdba803f..fd77cd62 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -12,17 +12,12 @@ import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart' import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:tuple/tuple.dart'; ///Responsible for creating a particular file structure depending in the structure /// ///For example, in the provider strategy, there would be a directory for the models and the providers, ///while something like BLoC will assign a directory to a single. /// -/// The [FileStructureStrategy] can also perform a dry run of the all the [writeDataToFile] calls -/// that are going to be performed. This is useful for notifying the [FileWriterObserver]s of new files that -/// are being written into the file system without actually writing them into the system. The main purpose -/// of this functionality is mimicking the file creation to observers like the [ImportHelper] can record all of the imports. abstract class FileStructureStrategy implements CommandInvoker { final Logger logger = Logger('FileStructureStrategy'); @@ -30,10 +25,10 @@ abstract class FileStructureStrategy implements CommandInvoker { /// ///The views is anything that is not a screen, for example, symbol masters ///are going to be generated in this folder if not specified otherwise. - final RELATIVE_VIEW_PATH = 'lib/widgets/'; + static final RELATIVE_VIEW_PATH = 'lib/widgets/'; ///The `default` path of where all the screens are going to be generated. - final RELATIVE_SCREEN_PATH = 'lib/screens/'; + static final RELATIVE_SCREEN_PATH = 'lib/screens/'; ///Path of where the project is generated final String GENERATED_PROJECT_PATH; @@ -59,24 +54,6 @@ abstract class FileStructureStrategy implements CommandInvoker { ///Before generating any files, the caller must call the [setUpDirectories] bool isSetUp = false; - /// The flag indicates when the [writeDataToFile] is going to mimic the creation - /// of the files. - /// - /// If [_inDryRunMode] is `true`, then any file creation is going to be simulated and remain on - /// hold on the [_dryRunMethodCalls] list. If you are running the [FileStructureStrategy] [_inDryRunMode], then - /// make sure to run [writeDryRunCommands] at the end to execute all the recored [writeDataToFile] calls. - bool _inDryRunMode = false; - set inDryRunMode(bool dryRun) => _inDryRunMode = dryRun; - - /// The flag, if `true`, notifies all the [FileWriterObserver]s twice when a file is created (assuming that its running in [_inDryRunMode]). - /// - /// If you want to only notify the [FileWriterObserver]s when the actual file is created, then - /// [_dryRunModeNotify] flag should be `false` - bool _dryRunModeNotify; - set dryRunModeNotify(bool notify) => _dryRunModeNotify = notify; - - List _dryRunMethodCalls; - String _screenDirectoryPath; String _viewDirectoryPath; @@ -84,9 +61,7 @@ abstract class FileStructureStrategy implements CommandInvoker { this.GENERATED_PROJECT_PATH, this._pageWriter, this._pbProject, - ) { - _dryRunMethodCalls = []; - } + ); void addFileObserver(FileWriterObserver observer) { if (observer != null) { @@ -137,6 +112,8 @@ abstract class FileStructureStrategy implements CommandInvoker { } } + @Deprecated('Please use the method [writeDataToFile] to write into the files') + ///Writing the code to the actual file /// ///The default computation of the function will foward the `code` to the @@ -159,16 +136,6 @@ abstract class FileStructureStrategy implements CommandInvoker { command.write(this); } - ///Going to run any [writeDataToFile] calls that just executed in [_inDryRunMode]. - void writeDryRunCommands() { - _dryRunMethodCalls.forEach((funcParams) => writeDataToFile( - funcParams.item1, funcParams.item2, funcParams.item3, - UUID: funcParams.item4)); - _dryRunMethodCalls.clear(); - } - - void clearDryRunCommands() => _dryRunMethodCalls.clear(); - /// Writing [data] into [directory] with the file [name] /// /// The [name] parameter should include the name of the file and the @@ -183,19 +150,11 @@ abstract class FileStructureStrategy implements CommandInvoker { {String UUID}) { var file = getFile(directory, name); - if (_inDryRunMode) { - _dryRunMethodCalls.add(Tuple4(data, directory, name, UUID)); - if (_dryRunModeNotify) { - fileObservers.forEach((observer) => observer.fileCreated( - file.path, UUID ?? p.basenameWithoutExtension(file.path))); - } - } else { - file.createSync(recursive: true); - file.writeAsStringSync(data); + file.createSync(recursive: true); + file.writeAsStringSync(data); - fileObservers.forEach((observer) => observer.fileCreated( - file.path, UUID ?? p.basenameWithoutExtension(file.path))); - } + fileObservers.forEach((observer) => observer.fileCreated( + file.path, UUID ?? p.basenameWithoutExtension(file.path))); } /// Appends [data] into [directory] with the file [name] diff --git a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart index af85f667..a0c51842 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; +import 'package:path/path.dart' as p; class ProviderFileStructureStrategy extends FileStructureStrategy { final RELATIVE_PROVIDER_PATH = 'lib/providers/'; @@ -13,8 +14,8 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { ProviderFileStructureStrategy( String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) : super(genProjectPath, pageWriter, pbProject) { - _providersPath = '$genProjectPath$RELATIVE_PROVIDER_PATH'; - _modelsPath = '$genProjectPath$RELATIVE_MODEL_PATH'; + _providersPath = p.join(genProjectPath, RELATIVE_PROVIDER_PATH); + _modelsPath = p.join(genProjectPath, RELATIVE_MODEL_PATH); } @override @@ -32,8 +33,6 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { } void writeProviderModelFile(String code, String fileName) { - super - .pageWriter - .write(code, '$_modelsPath$fileName.dart'); // Removed .g + super.pageWriter.write(code, '$_modelsPath$fileName.dart'); // Removed .g } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 4cd5e660..a928bd57 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,13 +1,15 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/generation/generators/util/topo_tree_iterator.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; @@ -18,7 +20,6 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -42,8 +43,12 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ///The default [PBGenerationManager] will be [PBFlutterGenerator] PBGenerationManager generationManager; + PBPlatformOrientationLinkerService poLinker; + ImportHelper _importProcessor; + @Deprecated('Use [FileStructureCommands instead of using the pageWriter.]') + /// PageWriter to be used for generation PBPageWriter pageWriter = PBFlutterWriter(); // Default to Flutter @@ -58,6 +63,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { _importProcessor ??= ImportHelper(); generationManager ??= PBFlutterGenerator(_importProcessor, data: PBGenerationViewData()); + poLinker ??= PBPlatformOrientationLinkerService(); } ///This is going to modify the [PBIntermediateNode] in order to affect the structural patterns or file structure produced. @@ -89,100 +95,121 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { return tree; } - ///Generates the [PBIntermediateTree]s within the [pb_project] - Future generateProject(PBProject pb_project) async { - var poLinker = PBPlatformOrientationLinkerService(); - - await setUpConfiguration(pb_project); - pb_project.fileStructureStrategy = fileStructureStrategy; - var trees = IntermediateTopoIterator(pb_project.forest); - - while (trees.moveNext()) { - var tree = trees.current; + Future generateTrees( + List trees, PBProject project) async { + for (var tree in trees) { + // var tree = trees.current; tree.rootNode.currentContext.generationManager = generationManager; - tree.data.addImport('package:flutter/material.dart'); + tree.data.addImport(FlutterImport('material.dart', 'flutter')); generationManager.data = tree.data; var fileName = tree.identifier?.snakeCase ?? 'no_name_found'; // Relative path to the file to create - var relPath = p.join(tree.name.snakeCase, '$fileName.dart'); + var relPath = + p.setExtension(p.join(tree.name.snakeCase, fileName), '.dart'); // Change relative path if current tree is part of multi-platform setup if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { var platformFolder = poLinker.stripPlatform(tree.rootNode.managerData.platform); - relPath = p.join(fileName, platformFolder, '$fileName'); + relPath = p.join(fileName, platformFolder, fileName); } if (tree.rootNode is InheritedScaffold && (tree.rootNode as InheritedScaffold).isHomeScreen) { await _setMainScreen(tree, relPath); } await _applyMiddleware(tree); - var command; - if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { - getPlatformOrientationName(tree.rootNode); - command = ExportPlatformCommand( - tree.UUID, - tree.rootNode.currentContext.tree.data.platform, - '$fileName', - '${tree.rootNode.name.snakeCase}.dart', - generationManager.generate(tree.rootNode), - ); - - if (_importProcessor.imports.isNotEmpty) { - var treePath = p.join( - pb_project.projectAbsPath, command.WIDGET_PATH, '$fileName.dart'); - _traverseTreeForImports(tree, treePath); - } - } else if (tree.rootNode is InheritedScaffold) { - command = WriteScreenCommand( - tree.UUID, - '$fileName.dart', - '${tree.name.snakeCase}', - generationManager.generate(tree.rootNode), - ); - - if (_importProcessor.imports.isNotEmpty) { - var treePath = p.join(pb_project.projectAbsPath, - WriteScreenCommand.SCREEN_PATH, '$fileName.dart'); - _traverseTreeForImports(tree, treePath); - } - } else { - command = WriteSymbolCommand( - tree.UUID, - '$fileName.dart', - generationManager.generate(tree.rootNode), - relativePath: '${tree.name.snakeCase}/', - ); - - if (_importProcessor.imports.isNotEmpty) { - var treePath = p.join(pb_project.projectAbsPath, command.SYMBOL_PATH, - command.relativePath, '$fileName.dart'); - _traverseTreeForImports(tree, treePath); - } + fileStructureStrategy + .commandCreated(_createCommand(fileName, tree, project)); + } + } + + ///Generates the [PBIntermediateTree]s within the [pb_project] + Future generateProject(PBProject pb_project) async { + ///First we are going to perform a dry run in the generation to + ///gather all the necessary information + configDryRun(pb_project); + pb_project.fileStructureStrategy = fileStructureStrategy; + await generateTrees(pb_project.forest, pb_project); + // var dryRunCommands = + // (fileStructureStrategy as DryRunFileStructureStrategy).dryRunCommands; + + ///After the dry run is complete, then we are able to create the actual files. + await setUpConfiguration(pb_project); + pb_project.fileStructureStrategy = fileStructureStrategy; + // dryRunCommands.forEach(fileStructureStrategy.commandCreated); + await generateTrees(pb_project.forest, pb_project); + + await _commitDependencies(pb_project.projectAbsPath); + } + + FileStructureCommand _createCommand( + String fileName, PBIntermediateTree tree, PBProject project) { + var command; + if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { + getPlatformOrientationName(tree.rootNode); + if (_importProcessor.imports.isNotEmpty) { + var treePath = p.join(project.projectAbsPath, + ExportPlatformCommand.WIDGET_PATH, fileName); + _traverseTreeForImports( + tree, p.setExtension(treePath, '.dart'), project.projectName); + } + command = ExportPlatformCommand( + tree.UUID, + tree.rootNode.currentContext.tree.data.platform, + fileName, + p.setExtension(tree.rootNode.name.snakeCase, '.dart'), + generationManager.generate(tree.rootNode), + ); + } else if (tree.rootNode is InheritedScaffold) { + if (_importProcessor.imports.isNotEmpty) { + var treePath = p.join( + project.projectAbsPath, WriteScreenCommand.SCREEN_PATH, fileName); + _traverseTreeForImports( + tree, p.setExtension(treePath, '.dart'), project.projectName); + } + command = WriteScreenCommand( + tree.UUID, + p.setExtension(fileName, '.dart'), + tree.name.snakeCase, + generationManager.generate(tree.rootNode), + ); + } else { + var relativePath = '${tree.name.snakeCase}/'; + if (_importProcessor.imports.isNotEmpty) { + var treePath = p.join(project.projectAbsPath, + WriteSymbolCommand.SYMBOL_PATH, relativePath, fileName); + _traverseTreeForImports( + tree, p.setExtension(treePath, '.dart'), project.projectName); } - fileStructureStrategy.commandCreated(command); + command = WriteSymbolCommand( + tree.UUID, + p.setExtension(fileName, '.dart'), + generationManager.generate(tree.rootNode), + relativePath: relativePath, + ); } - await _commitDependencies(pb_project.projectName); + return command; } /// Method that traverses `tree`'s dependencies and looks for an import path from /// [ImportHelper]. /// - /// If an import path is found, it will be added to the `tree`'s data. - void _traverseTreeForImports(PBIntermediateTree tree, String treeAbsPath) { + /// If an import path is found, it will be added to the `tree`'s data. The package format + /// for imports is going to be enforced, therefore, [packageName] is going to be + /// a required parameter. + void _traverseTreeForImports( + PBIntermediateTree tree, String treeAbsPath, String packageName) { var iter = tree.dependentOn; + var addImport = tree.rootNode.managerData.addImport; if (iter.moveNext()) { var dependency = iter.current; - for (var key in _importProcessor.imports.keys) { - if (key == dependency.UUID) { - var relativePath = PBGenCache().getRelativePathFromPaths( - treeAbsPath, _importProcessor.imports[key]); - tree.rootNode.managerData.addImport(relativePath); - } + var import = _importProcessor.getImport(dependency.UUID); + if (import != null) { + addImport(FlutterImport(import, packageName)); } } } @@ -194,6 +221,24 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } } + /// going to run the [generateProject] without actually creating or modifying any file + /// + /// The main purpose of this is to collect all the information necessary to run a successful + /// generation. For example, if we ran it normally, there would be imports missing because we could + /// not determine the final position of some dependencies. + FileStructureStrategy configDryRun(PBProject pbProject) { + fileStructureStrategy = DryRunFileStructureStrategy( + pbProject.projectAbsPath, pageWriter, pbProject); + fileStructureStrategy.addFileObserver(_importProcessor); + + ///TODO: Once [GenerationConfiguraion] is init from the beginning in PBC, we can remove the need of a queue + pbProject.genProjectData.commandQueue + .forEach(fileStructureStrategy.commandCreated); + + logger.info('Running Generation Dry Run...'); + return fileStructureStrategy; + } + ///Configure the required classes for the [PBGenerationConfiguration] Future setUpConfiguration(PBProject pbProject) async { fileStructureStrategy = FlutterFileStructureStrategy( @@ -211,10 +256,10 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await fileStructureStrategy.setUpDirectories(); } - Future _commitDependencies(String projectName) async { + Future _commitDependencies(String projectPath) async { var writer = pageWriter; if (writer is PBFlutterWriter) { - writer.submitDependencies(projectName + '/pubspec.yaml'); + writer.submitDependencies(p.join(projectPath, 'pubspec.yaml')); } } @@ -254,14 +299,14 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var rawImports = getPlatformImports(screenName); rawImports.add(p.join( - mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH + - OrientationBuilderCommand.DIR_TO_ORIENTATION_BUILDER + - OrientationBuilderCommand.NAME_TO_ORIENTAION_BUILDER, + mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH, + OrientationBuilderCommand.DIR_TO_ORIENTATION_BUILDER, + OrientationBuilderCommand.NAME_TO_ORIENTAION_BUILDER, )); rawImports.add(p.join( - mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH + - ResponsiveLayoutBuilderCommand.DIR_TO_RESPONSIVE_LAYOUT + - ResponsiveLayoutBuilderCommand.NAME_TO_RESPONSIVE_LAYOUT, + mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH, + ResponsiveLayoutBuilderCommand.DIR_TO_RESPONSIVE_LAYOUT, + ResponsiveLayoutBuilderCommand.NAME_TO_RESPONSIVE_LAYOUT, )); var newCommand = generatePlatformInstance( diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 29e5597a..889e6743 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -1,3 +1,5 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -105,7 +107,7 @@ mixin PBPlatformOrientationGeneration { String _serveImports(Set cookedImports) { var result = ''; cookedImports.forEach((import) { - result += 'import \'$import\';\n'; + result += FlutterImport(import).toString(); }); return result; } diff --git a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart index 96d576b1..4669aaef 100644 --- a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart @@ -1,3 +1,5 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/provider_middleware.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; @@ -7,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; +import 'package:path/path.dart' as p; class ProviderGenerationConfiguration extends GenerationConfiguration { ProviderGenerationConfiguration(); @@ -29,13 +32,13 @@ class ProviderGenerationConfiguration extends GenerationConfiguration { Future generateProject(PBProject pb_project) async { await super.generateProject(pb_project); if (pageWriter is PBFlutterWriter) { - Set imports = {'import \'package:provider/provider.dart\';'}; + Set imports = {FlutterImport('provider.dart', 'provider')}; imports.addAll(registeredModels - .map((e) => 'import \'models/${e.snakeCase}.dart\';') + .map((e) => FlutterImport('models/${e.snakeCase}.dart')) .toList()); (pageWriter as PBFlutterWriter).rewriteMainFunction( - fileStructureStrategy.GENERATED_PROJECT_PATH + 'lib/main.dart', + p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'lib/main.dart'), _generateMainFunction(), imports: imports, ); diff --git a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart index 52a58c0b..1eb2c243 100644 --- a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/riverpod_middleware.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; @@ -27,7 +28,7 @@ class RiverpodGenerationConfiguration extends GenerationConfiguration { (pageWriter as PBFlutterWriter).rewriteMainFunction( fileStructureStrategy.GENERATED_PROJECT_PATH + 'lib/main.dart', _generateMainFunction(), - imports: {"import 'package:flutter_riverpod/flutter_riverpod.dart';"}, + imports: {FlutterImport('flutter_riverpod.dart', 'flutter_riverpod')}, ); } } diff --git a/lib/generation/generators/visual-widgets/pb_text_gen.dart b/lib/generation/generators/visual-widgets/pb_text_gen.dart index 5627d21f..9f66a731 100644 --- a/lib/generation/generators/visual-widgets/pb_text_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_text_gen.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/design_logic/color.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; @@ -15,7 +16,7 @@ class PBTextGen extends PBGenerator with PBColorMixin { .addDependencies('auto_size_text', '^2.1.0'); source.managerData - .addImport('package:auto_size_text/auto_size_text.dart'); + .addImport(FlutterImport('auto_size_text.dart', 'auto_size_text')); var buffer = StringBuffer(); buffer.write('AutoSizeText(\n'); var isTextParameter = source.isTextParameter; diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index c577c405..a95770a3 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; ///Responsible for writing code into files in the desired folder structure @@ -39,7 +40,7 @@ class PBFlutterWriter implements PBPageWriter { /// Function that allows the rewriting of the main() method inside main.dart void rewriteMainFunction(String pathToMain, String code, - {Set imports}) { + {Set imports}) { var mainRead = File(pathToMain).readAsStringSync(); var newMain = imports.join() + mainRead.replaceFirst( diff --git a/lib/generation/pre-generation/pre_generation_service.dart b/lib/generation/pre-generation/pre_generation_service.dart deleted file mode 100644 index b94ae273..00000000 --- a/lib/generation/pre-generation/pre_generation_service.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:archive/archive.dart'; -import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_linker.dart'; - -/// Singleton class that leverages the traversal adapter -/// to traverse and save metadata to the Tree -class PreGenerationService extends FlutterProjectBuilder { - PreGenerationService({ - String projectName, - PBProject mainTree, - PBPageWriter pageWriter, - }) : super( - projectName: projectName, - mainTree: mainTree, - pageWriter: pageWriter, - ); - - @override - Future convertToFlutterProject({List rawImages}) async { - // TODO: This could be moved one level up to Controllers since - // it is currently in here and FlutterProjectBuilder - await Future.wait(PBStateManagementLinker().stateQueue); - await generationConfiguration.generateProject(mainTree); - } -} From beed3a32498761989dd5ad51ac459fa3238164af Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Thu, 27 May 2021 13:05:08 -0700 Subject: [PATCH 145/404] Sends the right templateStrategy to the padding calculation to use the right constraints --- lib/generation/generators/visual-widgets/pb_padding_gen.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/visual-widgets/pb_padding_gen.dart b/lib/generation/generators/visual-widgets/pb_padding_gen.dart index 413a9323..1a3a38e2 100644 --- a/lib/generation/generators/visual-widgets/pb_padding_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_padding_gen.dart @@ -48,7 +48,7 @@ class PBPaddingGen extends PBGenerator { } if (value != null) { buffer.write( - '$position: ${relativePadding(source.generator.templateStrategy, isVertical, value)},'); + '$position: ${relativePadding(source.currentContext.treeRoot.rootNode.generator.templateStrategy, isVertical, value)},'); } } @@ -56,7 +56,7 @@ class PBPaddingGen extends PBGenerator { var value = reflectedPadding.getField(Symbol(position)).reflectee; if (value != null) { buffer.write( - '$position: ${relativePadding(source.generator.templateStrategy, true, value)},'); + '$position: ${relativePadding(source.currentContext.treeRoot.rootNode.generator.templateStrategy, true, value)},'); } } From 897519a9fa37eeab4b5ce79a92caa1d96b7c459a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 27 May 2021 17:47:03 -0600 Subject: [PATCH 146/404] Add nullchecker for styles and changed length checker to `isNotEmpty` --- .../middleware/state_management/utils/middleware_utils.dart | 2 +- lib/input/sketch/entities/style/style.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index e4b0c785..3c034e61 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -81,7 +81,7 @@ class MiddlewareUtils { ${defaultStateName}(){} // default provider event handler for gestures. - void OnGesture() { + void onGesture() { } void setCurrentWidget(Widget currentWidget) { diff --git a/lib/input/sketch/entities/style/style.dart b/lib/input/sketch/entities/style/style.dart index d8343b47..f2bf50c2 100644 --- a/lib/input/sketch/entities/style/style.dart +++ b/lib/input/sketch/entities/style/style.dart @@ -61,7 +61,7 @@ class Style implements PBStyle { hasShadow = true; } // TODO: add rectangle fill types, for now just copy the fill[0] to the background color - if (fills.length >= 1) { + if (fills != null && fills.isNotEmpty) { if (fills[0].isEnabled && (fills[0].fillType == 0)) { backgroundColor = fills[0].color; } From 7e71fc7f1bb2f1902f20ba4eb4f2f3733bc1ba25 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 18 May 2021 21:10:36 -0600 Subject: [PATCH 147/404] Fix check-git.sh always saying SAC is out of date --- pb-scripts/check-git.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pb-scripts/check-git.sh b/pb-scripts/check-git.sh index be14bc2f..b576318e 100755 --- a/pb-scripts/check-git.sh +++ b/pb-scripts/check-git.sh @@ -19,8 +19,8 @@ then currentCom=`git rev-parse HEAD` echo "Downloading submodule SketchAssetConverter" else - masterCom=`git rev-parse @:./SketchAssetConverter` - # echo $masterCom + cd .. + masterCom=`git rev-parse @:SketchAssetConverter` if [ $masterCom == $currentCom ] then From f41c2126ca795c717fe63f1066c29a1710d92ccd Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Thu, 27 May 2021 19:23:03 -0600 Subject: [PATCH 148/404] Imports for the prototypes are working now, the only ones missing are the states. --- .../state_management/stateful_middleware.dart | 14 ++-- .../commands/entry_file_command.dart | 69 +++++++++++++++++++ .../commands/export_platform_command.dart | 3 +- .../pb_generation_configuration.dart | 22 +++--- .../generators/writers/pb_flutter_writer.dart | 4 +- .../helpers/pb_intermediate_node_tree.dart | 3 +- pubspec.yaml | 2 +- 7 files changed, 95 insertions(+), 22 deletions(-) create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index ab7aa726..2b057b1e 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -1,10 +1,12 @@ import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; +import 'package:path/path.dart' as p; class StatefulMiddleware extends Middleware { StatefulMiddleware(PBGenerationManager generationManager) @@ -38,11 +40,15 @@ class StatefulMiddleware extends Middleware { return node; } - String getImportPath(PBSharedInstanceIntermediateNode node, fileStrategy) { + String getImportPath(PBSharedInstanceIntermediateNode node, + FileStructureStrategy fileStrategy) { var symbolMaster = PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); - return fileStrategy.GENERATED_PROJECT_PATH + - fileStrategy.RELATIVE_VIEW_PATH + - '${getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; + var path = p.join( + fileStrategy.GENERATED_PROJECT_PATH, + FileStructureStrategy.RELATIVE_VIEW_PATH, + getName(symbolMaster.name).snakeCase, + node.functionCallName.snakeCase); + return p.setExtension(path, '.dart'); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart new file mode 100644 index 00000000..b40cb547 --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart @@ -0,0 +1,69 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:path/path.dart' as p; + +/// [FileStructureCommand] used towrite the internals of the entry file. +/// +/// For example, the modifying the code for `main.dart`, modifying the first screen +/// or adding/removing the imports, etc. +class EntryFileCommand extends NodeFileStructureCommand { + ///The name for the file that is the entry point for the flutter application. + final String mainFileName; + + /// The name of the screen that is going to act as the entry point within the [mainFileName] + final String entryScreenName; + + /// The import for [entryScreenName] + final String entryScreenImport; + + /// The name of the application as a whole. If no name is specified, the its going to default to + /// `Parabeac-Core Generated Project`. + final String projectName; + + /// The code of the main() method inside [mainFileName] + final String mainCode; + + EntryFileCommand(String UUID, + {this.mainFileName = 'main', + this.entryScreenName, + this.entryScreenImport, + this.projectName = 'Parabeac-Core Generated Project', + this.mainCode = 'runApp(MyApp());'}) + : super(UUID, ''' +import 'package:flutter/material.dart'; +$entryScreenImport + +void main() { + $mainCode +} + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: '$projectName', + theme: ThemeData( + primarySwatch: Colors.blue, + visualDensity: VisualDensity.adaptivePlatformDensity, + ), + home: $entryScreenName(), + ); + } +} + + ''') { + if ((entryScreenImport == null && entryScreenName != null) || + (entryScreenName == null && entryScreenName != null)) { + throw NullThrownError(); + } + } + + @override + Future write(FileStructureStrategy strategy) { + strategy.writeDataToFile(code, strategy.GENERATED_PROJECT_PATH, + p.setExtension(p.join('lib', mainFileName), '.dart'), + UUID: UUID); + } +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index a0ab583b..740a6010 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -22,7 +22,8 @@ class ExportPlatformCommand extends NodeFileStructureCommand { Future write(FileStructureStrategy strategy) async { var path = p.join( strategy.GENERATED_PROJECT_PATH, - '$WIDGET_PATH/$folderName/', + WIDGET_PATH, + folderName, platform.toString().toLowerCase().replaceAll('platform.', ''), ); strategy.writeDataToFile(code, path, fileName, UUID: UUID); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index a928bd57..51821065 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; @@ -29,6 +30,7 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orient import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; import 'package:path/path.dart' as p; +import 'package:uuid/uuid.dart'; abstract class GenerationConfiguration with PBPlatformOrientationGeneration { FileStructureStrategy fileStructureStrategy; @@ -117,7 +119,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } if (tree.rootNode is InheritedScaffold && (tree.rootNode as InheritedScaffold).isHomeScreen) { - await _setMainScreen(tree, relPath); + await _setMainScreen(tree, relPath, project.projectName); } await _applyMiddleware(tree); @@ -133,8 +135,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { configDryRun(pb_project); pb_project.fileStructureStrategy = fileStructureStrategy; await generateTrees(pb_project.forest, pb_project); - // var dryRunCommands = - // (fileStructureStrategy as DryRunFileStructureStrategy).dryRunCommands; ///After the dry run is complete, then we are able to create the actual files. await setUpConfiguration(pb_project); @@ -205,7 +205,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var iter = tree.dependentOn; var addImport = tree.rootNode.managerData.addImport; - if (iter.moveNext()) { + while (iter.moveNext()) { var dependency = iter.current; var import = _importProcessor.getImport(dependency.UUID); if (import != null) { @@ -264,15 +264,13 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } Future _setMainScreen( - PBIntermediateTree tree, String outputMain) async { - var writer = pageWriter; + PBIntermediateTree tree, String outputMain, String packageName) async { var nodeInfo = _determineNode(tree, outputMain); - if (writer is PBFlutterWriter) { - await writer.writeMainScreenWithHome( - nodeInfo[0], - p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'lib/main.dart'), - 'screens/${nodeInfo[1]}'); - } + fileStructureStrategy.commandCreated(EntryFileCommand('main_file', + entryScreenName: nodeInfo[0], + entryScreenImport: + FlutterImport(_importProcessor.getImport(tree.UUID), packageName) + .toString())); } List _determineNode(PBIntermediateTree tree, String outputMain) { diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index a95770a3..4a64bc27 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -51,11 +51,11 @@ class PBFlutterWriter implements PBPageWriter { /// Creates a new `main.dart` file that starts the Flutter application at /// `homeName` and adds the import from `main.dart` to `relativeImportPath`. Future writeMainScreenWithHome( - String homeName, String pathToMain, String relativeImportPath) async { + String homeName, String pathToMain, FlutterImport import) async { var mainFile = File(pathToMain).openWrite(mode: FileMode.writeOnly); mainFile.write(''' import 'package:flutter/material.dart'; -import '$relativeImportPath'; +import '${import.toString()}'; void main() { runApp(MyApp()); diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index e8ad4105..43f6ca35 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -27,8 +27,7 @@ class PBIntermediateTree extends Iterable { /// /// In other words, `this` can not be generated until its [dependentsOn]s are generated. Set _dependentsOn; - Iterator get dependentOn => - _dependentsOn.where((depedent) => depedent != null).iterator; + Iterator get dependentOn => _dependentsOn.iterator; String name; String identifier; diff --git a/pubspec.yaml b/pubspec.yaml index 336db1b8..34285632 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,7 +21,7 @@ dependencies: recase: "^3.0.0" tuple: ^1.0.3 azblob: ^1.0.3 -# path: ^1.6.0 + path: ^1.6.0 dev_dependencies: pedantic: ^1.8.0 From 90e79bfac3c03b88e132b59ef9007b995b40ee18 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 26 May 2021 16:42:27 -0600 Subject: [PATCH 149/404] Replace dartfmt for dart format command --- .../flutter_project_builder/flutter_project_builder.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index f7d1bb57..79638f8f 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -157,9 +157,9 @@ class FlutterProjectBuilder { log.info( Process.runSync( - 'dartfmt', + 'dart', [ - '-w', + 'format', '${pathToFlutterProject}bin', '${pathToFlutterProject}lib', '${pathToFlutterProject}test' From 9ee882c2b9207fd963dcff625778f7f427f82b78 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 18 May 2021 22:43:14 -0600 Subject: [PATCH 150/404] Provider no longer generates final global vars --- .../state_management/provider_middleware.dart | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 111863ca..6618cffc 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -2,10 +2,8 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.d import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; -import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; @@ -33,15 +31,6 @@ class ProviderMiddleware extends Middleware { .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); managerData.addImport('package:provider/provider.dart'); watcherName = getVariableName(node.name.snakeCase + '_notifier'); - var widgetName = node.functionCallName.camelCase; - var watcher; - - if (node.currentContext.treeRoot.rootNode.generator.templateStrategy - is StatelessTemplateStrategy) { - watcher = PBVariable(watcherName, 'final ', true, - '${ImportHelper.getName(node.functionCallName).pascalCase}().${widgetName}'); - //managerData.addGlobalVariable(watcher); - } addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); PBGenCache().appendToCache(node.SYMBOL_ID, From 5c136c73a1337be39fa9c35c7420fcef7b0a7c05 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 24 May 2021 10:36:29 -0600 Subject: [PATCH 151/404] Replace `context.watch()` with `Consumer` widget --- .../middleware/state_management/provider_middleware.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 6618cffc..70d970a1 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -55,9 +55,9 @@ class ProviderMiddleware extends Middleware { return GestureDetector( onTap: () => context.read< ${modelName}>().OnGesture(), - child: context - .watch<${modelName}>() - .currentWidget, + child: Consumer<$modelName>( + builder: (context, ${modelName.toLowerCase()}, child) => ${modelName.toLowerCase()}.currentWidget + ), ); }, ), From 98728476bcf4dddd2e971c1f37990bb81077534c Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 24 May 2021 10:37:47 -0600 Subject: [PATCH 152/404] Remove generation of `providers` folder --- .../provider_file_structure_strategy.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart index b65cd8ba..3752095a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart @@ -5,15 +5,12 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; class ProviderFileStructureStrategy extends FileStructureStrategy { - final RELATIVE_PROVIDER_PATH = 'lib/providers/'; final RELATIVE_MODEL_PATH = 'lib/models/'; - var _providersPath; var _modelsPath; ProviderFileStructureStrategy( String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) : super(genProjectPath, pageWriter, pbProject) { - _providersPath = '${genProjectPath}${RELATIVE_PROVIDER_PATH}'; _modelsPath = '${genProjectPath}${RELATIVE_MODEL_PATH}'; } @@ -27,7 +24,6 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { } Future _generateMissingDirectories() async { - Directory(_providersPath).createSync(recursive: true); Directory(_modelsPath).createSync(recursive: true); } From d95f483eb5e052f2a42aab5f979c6822faeb27c5 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 27 May 2021 17:47:03 -0600 Subject: [PATCH 153/404] Add nullchecker for styles and changed length checker to `isNotEmpty` --- .../middleware/state_management/utils/middleware_utils.dart | 2 +- lib/input/sketch/entities/style/style.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index e4b0c785..3c034e61 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -81,7 +81,7 @@ class MiddlewareUtils { ${defaultStateName}(){} // default provider event handler for gestures. - void OnGesture() { + void onGesture() { } void setCurrentWidget(Widget currentWidget) { diff --git a/lib/input/sketch/entities/style/style.dart b/lib/input/sketch/entities/style/style.dart index d8343b47..f2bf50c2 100644 --- a/lib/input/sketch/entities/style/style.dart +++ b/lib/input/sketch/entities/style/style.dart @@ -61,7 +61,7 @@ class Style implements PBStyle { hasShadow = true; } // TODO: add rectangle fill types, for now just copy the fill[0] to the background color - if (fills.length >= 1) { + if (fills != null && fills.isNotEmpty) { if (fills[0].isEnabled && (fills[0].fillType == 0)) { backgroundColor = fills[0].color; } From 23d38f30282966e218d1c57b791b649a31682874 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 18 May 2021 21:10:36 -0600 Subject: [PATCH 154/404] Fix check-git.sh always saying SAC is out of date --- pb-scripts/check-git.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pb-scripts/check-git.sh b/pb-scripts/check-git.sh index be14bc2f..b576318e 100755 --- a/pb-scripts/check-git.sh +++ b/pb-scripts/check-git.sh @@ -19,8 +19,8 @@ then currentCom=`git rev-parse HEAD` echo "Downloading submodule SketchAssetConverter" else - masterCom=`git rev-parse @:./SketchAssetConverter` - # echo $masterCom + cd .. + masterCom=`git rev-parse @:SketchAssetConverter` if [ $masterCom == $currentCom ] then From f71e0f7b61b72c9dcf6c6a64ee7a4de98650f893 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sat, 29 May 2021 20:02:00 -0700 Subject: [PATCH 155/404] overrides and friendly names now completely work, need to figure out what if anything the prop.value is used for in gatherSharedParameters function. --- lib/configurations/configurations.json | 2 +- .../utils/middleware_utils.dart | 14 ++-- .../symbols/pb_instancesym_gen.dart | 21 +++--- .../stateless_template_strategy.dart | 2 + lib/input/figma/entities/layers/instance.dart | 12 ++++ .../sketch/entities/layers/symbol_master.dart | 4 ++ .../sketch/helper/symbol_node_mixin.dart | 66 ++++++++++++------- .../entities/pb_shared_instance.dart | 2 +- .../entities/pb_shared_master_node.dart | 2 +- .../pb_shared_aggregation_service.dart | 27 +++++--- .../pb_symbol_instance_overridable_value.dart | 2 +- .../pb_symbol_master_params.dart | 4 +- 12 files changed, 105 insertions(+), 53 deletions(-) diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index 26ca0fa6..4eab6a44 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -5,5 +5,5 @@ "widgetSpacing": "Expanded", "layoutPrecedence": ["column", "row", "stack"] }, - "state-management": "none" + "state-management": "provider" } diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 3c034e61..0d189592 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -100,11 +100,15 @@ class MiddlewareUtils { {String type = 'var'}) => '${type} ${node.name.camelCase};'; - static String generateVariableBody(node) => - (node?.generator?.generate(node ?? '', - GeneratorContext(sizingContext: SizingValueContext.PointValue)) ?? - '') + - ';'; + static String generateVariableBody(node) { + node?.managerData?.hasParams = true; + String genCode = (node?.generator?.generate(node ?? '', + GeneratorContext(sizingContext: SizingValueContext.PointValue)) ?? + '') + + ';'; + node?.managerData?.hasParams = false; + return genCode; + } static String wrapOnLayout(String className) { return ''' diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index b508970d..6ded4414 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -11,7 +11,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.d import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; @@ -33,8 +32,8 @@ class PBSymbolInstanceGenerator extends PBGenerator { buffer.write(' builder: (context, constraints) {\n'); buffer.write(' return '); - // If storage found an instance, get its master - var masterSymbol = + // If we are processing master symbol generation grab the master, else grab gab the master of ourselves + var masterSymbol = generatorContext.masterNode ?? PBSymbolStorage().getSharedMasterNodeBySymbolID(source.SYMBOL_ID); // recursively generate Symbol Instance constructors with overrides @@ -74,8 +73,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { Map mapOverrideValues, Map mapParameterValues, PBGenerationViewData managerData, - { bool topLevel = true, - String UUIDPath = ''}) { + { String UUIDPath = ''}) { if ((UUID == null) || (UUID == '')) { return ''; } @@ -121,7 +119,6 @@ class PBSymbolInstanceGenerator extends PBGenerator { masterSymbol.parametersDefsMap.forEach((overrideName, smParameter) { var ovrValue = ''; - overrideName = UUIDPath + overrideName; if (mapOverrideValues.containsKey(overrideName)) { var param = mapOverrideValues[overrideName]; switch (param.type) { @@ -131,7 +128,6 @@ class PBSymbolInstanceGenerator extends PBGenerator { mapOverrideValues, mapParameterValues, managerData, - topLevel: false, UUIDPath: '$UUIDPath${param.UUID}/', ); break; @@ -159,20 +155,21 @@ class PBSymbolInstanceGenerator extends PBGenerator { } } // get parameter name to pass to widget constructor - var friendlyName = SN_UUIDtoVarName[ - PBInputFormatter.findLastOf(smParameter.propertyName, '/')]; + var widgetParamName = SN_UUIDtoVarName[PBInputFormatter.findLastOf(smParameter.propertyName, '/')]; + // our parent widget parameter name, defaults to blank no such parameter. var paramName = ''; // check if parent widget has parameter to pass down to children + var paramPropertyName = '$UUIDPath$UUID/${smParameter.propertyName}'; if (managerData.hasParams && - mapParameterValues.containsKey(smParameter.propertyName)) { + mapParameterValues.containsKey(paramPropertyName)) { // yes, so pass down with optional null check - paramName = friendlyName; + paramName = SN_UUIDtoVarName[paramPropertyName]; if (ovrValue != '') { paramName += ' ?? '; } } if ((ovrValue != '') || (paramName != '')) { - buffer.write('$friendlyName: $paramName$ovrValue,\n'); + buffer.write('$widgetParamName: $paramName$ovrValue,\n'); } }); diff --git a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart index d360e6c0..3c2dc30c 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/generation/generators/value_objects/template_strat import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; class StatelessTemplateStrategy extends TemplateStrategy { @@ -18,6 +19,7 @@ class StatelessTemplateStrategy extends TemplateStrategy { var overrides = ''; var overrideVars = ''; + print('${PBSymbolStorage().sharedMasterNodes.length}'); if (node is PBSharedMasterNode && node.overridableProperties.isNotEmpty) { node.overridableProperties.forEach((prop) { overrides += 'this.${prop.friendlyName}, '; diff --git a/lib/input/figma/entities/layers/instance.dart b/lib/input/figma/entities/layers/instance.dart index d8694fa9..afa84254 100644 --- a/lib/input/figma/entities/layers/instance.dart +++ b/lib/input/figma/entities/layers/instance.dart @@ -111,6 +111,18 @@ class Instance extends FigmaFrame throw UnimplementedError(); } + @override + String MakeFriendlyName(String inName, Type type) { + // TODO: implement AddMasterSymbolOverrideName + throw UnimplementedError(); + } + + @override + String GetUniqueVarName(String overrideName, String friendlyName) { + // TODO: implement AddMasterSymbolOverrideName + throw UnimplementedError(); + } + @override String FindName(String uuid, List children, Type type) { // TODO: implement FindName diff --git a/lib/input/sketch/entities/layers/symbol_master.dart b/lib/input/sketch/entities/layers/symbol_master.dart index 303ad310..48ba9204 100644 --- a/lib/input/sketch/entities/layers/symbol_master.dart +++ b/lib/input/sketch/entities/layers/symbol_master.dart @@ -59,6 +59,8 @@ class SymbolMaster extends AbstractGroupLayer Style _style; + static Map SN_SymbolMasters; + @override void set isVisible(bool _isVisible) => this._isVisible = _isVisible; @@ -148,6 +150,8 @@ class SymbolMaster extends AbstractGroupLayer if (name != null) { this.name = name?.replaceAll(RegExp(r'[\s_\+]'), ''); this.name = PBInputFormatter.removeFirstDigits(name); + SN_SymbolMasters ??= {}; + SN_SymbolMasters[symbolID] = this; } } diff --git a/lib/input/sketch/helper/symbol_node_mixin.dart b/lib/input/sketch/helper/symbol_node_mixin.dart index 42b45f5b..5117fbd2 100644 --- a/lib/input/sketch/helper/symbol_node_mixin.dart +++ b/lib/input/sketch/helper/symbol_node_mixin.dart @@ -2,10 +2,13 @@ import 'dart:core'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; +import 'package:parabeac_core/input/sketch/entities/layers/symbol_instance.dart'; +import 'package:parabeac_core/input/sketch/entities/layers/symbol_master.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/entities/style/text_style.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; // both need to be global because a symbol instance could have multiple master symbols with name conflicts @@ -21,23 +24,53 @@ mixin SymbolNodeMixin { PBSharedInstanceIntermediateNode: 'sv', }; + String GetUniqueVarName(String overrideName, String friendlyName) { + String varName; + + // only increase count, make new varName if unique UUID + if (!SN_UUIDtoVarName.containsKey(overrideName)) { + var count = varNameCount[friendlyName] ?? 0; + varName = friendlyName; + varNameCount[friendlyName] = count + 1; + // first one doesn't have appended number + if (count > 0) { + varName += count.toString(); + } + SN_UUIDtoVarName[overrideName] = varName; + } else { + varName = SN_UUIDtoVarName[overrideName]; + } + + return varName; + } + + String MakeFriendlyName(String inName, Type type) { + var name = ((typeToAbbreviation[type] ?? 'un') + ' ' + (inName ?? 'var')) + .camelCase; + return name.replaceAll( + RegExp( + r'[^A-Za-z0-9_]', + ), + ''); + } // should have been a Map but iterate slowly through the list String FindName(String uuid, List children, Type type) { for (var child in children) { if (child.UUID == uuid) { - var name = - ((typeToAbbreviation[type] ?? 'un') + ' ' + (child.name ?? 'var')) - .camelCase; - return name.replaceAll( - RegExp( - r'[^A-Za-z0-9_]', - ), - ''); + return MakeFriendlyName(child.name, type); } else if (child is AbstractGroupLayer) { var found = FindName(uuid, child.children, type); if (found != null) { return found; } + } else if (child is SymbolInstance) { + var masterSymbol = SymbolMaster.SN_SymbolMasters[child.symbolID]; + if (masterSymbol != null) { + var found = FindName(uuid, masterSymbol.children, type); + if (found != null) { + return found; + } + } } } // return null to indicate not found @@ -47,24 +80,11 @@ mixin SymbolNodeMixin { Map AddMasterSymbolOverrideName(String overrideName, List children) { var varName; var parmInfo = extractParameter(overrideName); - var uuid = parmInfo['uuid']; + var uuid = PBInputFormatter.findLastOf(parmInfo['uuid'], '/'); var nodeName = FindName(uuid, children, parmInfo['type']); - // only add names of our direct descendants if (nodeName != null) { - // only increase count, make new varName if unique UUID - if (!SN_UUIDtoVarName.containsKey(overrideName)) { - var count = varNameCount[nodeName] ?? 0; - varName = nodeName; - varNameCount[nodeName] = count + 1; - // first one doesn't have appended number - if (count > 0) { - varName += count.toString(); - } - SN_UUIDtoVarName[overrideName] = varName; - } else { - varName = SN_UUIDtoVarName[overrideName]; - } + varName = GetUniqueVarName(overrideName, nodeName); } return {'name': varName, 'type': parmInfo['type'], 'uuid': uuid}; } diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 10c6963d..6b3e2019 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -102,7 +102,7 @@ class PBSharedParameterValue { final String _overrideName; String get overrideName => _overrideName; - String get name => SN_UUIDtoVarName[PBInputFormatter.findLastOf(_overrideName, '/')]; + String get friendlyName => SN_UUIDtoVarName[_overrideName]; PBSharedParameterValue( this._type, diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index b970616f..71428cc2 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -138,7 +138,7 @@ class PBSharedParameterProp { dynamic get initialValue => _initialValue; final String _friendlyName; - String get friendlyName => _friendlyName ?? SN_UUIDtoVarName[PBInputFormatter.findLastOf(propertyName, '/')] ?? 'noname'; + String get friendlyName => SN_UUIDtoVarName[propertyName] ?? 'noname'; PBSharedParameterProp(this._friendlyName, this._type, this.value, this._canOverride, this._propertyName, this._UUID, this._initialValue); diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index 7cd0ae08..f08641b9 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -47,22 +47,33 @@ class PBSharedInterAggregationService { ///are going to look for its [PBSharedParameterValue] if it does not have one. void gatherSharedParameters( PBSharedMasterNode sharedMasterNode, PBIntermediateNode rootChildNode) { + + // first fill in any Shared Instances before we can check our overridable properties are in the tree + for (var prop in sharedMasterNode.overridableProperties) { + var targetUUID = prop?.UUID; + if (prop.type == PBSharedInstanceIntermediateNode) { + prop.value = PBIntermediateNodeSearcherService.searchNodeByUUID( + rootChildNode, targetUUID); + if (prop.value != null) { + ///if the [PBSharedMasterNode] contains [PBSharedInstanceIntermediateNode] as parameters + ///then its going gather the information of its [PBSharedMasterNode]. + gatherSharedValues(prop.value); + } + } + } + for (var prop in sharedMasterNode.overridableProperties) { - var targetUUID = PBInputFormatter.findLastOf(prop?.UUID, '/'); + var targetUUID = prop?.UUID; prop.value = PBIntermediateNodeSearcherService.searchNodeByUUID( rootChildNode, targetUUID); if (prop.value == null) { // add Designer Warning here, not even sure if this is the designers fault or not log.warning('UUID: ${targetUUID} not found in searchNodeByUUID'); } - if ((prop.value != null) && (prop.type == PBSharedInstanceIntermediateNode)) { - ///if the [PBSharedMasterNode] contains [PBSharedInstanceIntermediateNode] as parameters - ///then its going gather the information of its [PBSharedMasterNode]. - gatherSharedValues(prop.value); - } } - sharedMasterNode.overridableProperties - .removeWhere((prop) => prop == null || prop.value == null); + + //sharedMasterNode.overridableProperties + // .removeWhere((prop) => prop == null || prop.value == null); } ///Its going to check the [PBSharedInstanceIntermediateNode]s and the [PBSharedMasterNode]s that are coming through diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart index a596a56a..b90fc084 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart @@ -9,7 +9,7 @@ class PBSymbolInstanceOverridableValue { final String UUID; final dynamic value; - String get friendlyName => SN_UUIDtoVarName[PBInputFormatter.findLastOf(UUID, '/')] ?? 'noname'; + String get friendlyName => SN_UUIDtoVarName[UUID] ?? 'noname'; PBSymbolInstanceOverridableValue(this.UUID, this.value, this.type); diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart index ca5727b2..7c86bebe 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart @@ -30,7 +30,9 @@ class PBSymbolMasterParameter extends PBVisualIntermediateNode this.bottomRightX, this.bottomRightY, {this.context}) - : super(Point(0, 0), Point(0, 0), context, name); + : super(Point(0, 0), Point(0, 0), context, name) { + + } static String _typeToJson(type) { return type.toString(); From 49e32f7893bf4be1b28db1b06078b8a36fe4b00a Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sat, 29 May 2021 20:41:10 -0700 Subject: [PATCH 156/404] removing debug print I accidently introduced --- .../template_strategy/stateless_template_strategy.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart index 3c2dc30c..17df5798 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart @@ -19,7 +19,6 @@ class StatelessTemplateStrategy extends TemplateStrategy { var overrides = ''; var overrideVars = ''; - print('${PBSymbolStorage().sharedMasterNodes.length}'); if (node is PBSharedMasterNode && node.overridableProperties.isNotEmpty) { node.overridableProperties.forEach((prop) { overrides += 'this.${prop.friendlyName}, '; From b3d5d98b415e5a35850feba025a9655d0174a29b Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Sun, 30 May 2021 00:01:15 -0600 Subject: [PATCH 157/404] Added basis for PBDL Pinning & Resizing --- lib/input/sketch/entities/layers/bitmap.dart | 7 ++++-- lib/input/sketch/entities/layers/group.dart | 5 +++- lib/input/sketch/entities/layers/oval.dart | 4 +++- lib/input/sketch/entities/layers/polygon.dart | 4 +++- .../sketch/entities/layers/rectangle.dart | 1 + .../sketch/entities/layers/shape_group.dart | 4 +++- .../sketch/entities/layers/shape_path.dart | 4 +++- .../sketch/entities/layers/sketch_text.dart | 4 ++-- lib/input/sketch/entities/layers/star.dart | 9 ++++++-- .../entities/layers/symbol_instance.dart | 10 +++++--- .../sketch/entities/layers/triangle.dart | 4 +++- .../helper/sketch_constraint_to_pbdl.dart | 7 ++++++ .../entities/inherited_bitmap.dart | 15 ++++++------ .../entities/inherited_container.dart | 23 +++++++++---------- .../entities/inherited_oval.dart | 6 +++-- .../entities/inherited_polygon.dart | 6 +++-- .../entities/inherited_shape_group.dart | 6 +++-- .../entities/inherited_shape_path.dart | 6 +++-- .../entities/inherited_star.dart | 6 +++-- .../entities/inherited_triangle.dart | 6 +++-- .../entities/injected_container.dart | 4 +++- .../layouts/temp_group_layout_node.dart | 6 ++--- .../entities/pb_shared_instance.dart | 19 +++++++-------- .../subclasses/pb_intermediate_node.dart | 5 +++- .../pb_visual_intermediate_node.dart | 6 +++-- .../entities/subclasses/pbdl_constraints.dart | 9 ++++++++ 26 files changed, 124 insertions(+), 62 deletions(-) create mode 100644 lib/input/sketch/helper/sketch_constraint_to_pbdl.dart create mode 100644 lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart diff --git a/lib/input/sketch/entities/layers/bitmap.dart b/lib/input/sketch/entities/layers/bitmap.dart index 7e3333d1..0863b530 100644 --- a/lib/input/sketch/entities/layers/bitmap.dart +++ b/lib/input/sketch/entities/layers/bitmap.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -110,8 +111,10 @@ class Bitmap extends SketchNode implements SketchNodeFactory, Image { if (intermediateNode != null) { return intermediateNode; } - return Future.value( - InheritedBitmap(this, name, currentContext: currentContext)); + return Future.value(InheritedBitmap(this, name, + currentContext: currentContext, + constraints: + convertSketchConstraintToPBDLConstraint(resizingConstraint))); } @JsonKey(name: 'image') diff --git a/lib/input/sketch/entities/layers/group.dart b/lib/input/sketch/entities/layers/group.dart index aa5bf2a1..2c442381 100644 --- a/lib/input/sketch/entities/layers/group.dart +++ b/lib/input/sketch/entities/layers/group.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -120,7 +121,9 @@ class Group extends AbstractGroupLayer implements SketchNodeFactory { topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), bottomRightCorner: Point( boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height))); + boundaryRectangle.y + boundaryRectangle.height), + constraints: + convertSketchConstraintToPBDLConstraint(resizingConstraint))); @override Map toPBDF() => { diff --git a/lib/input/sketch/entities/layers/oval.dart b/lib/input/sketch/entities/layers/oval.dart index 37931bbc..e6456b59 100644 --- a/lib/input/sketch/entities/layers/oval.dart +++ b/lib/input/sketch/entities/layers/oval.dart @@ -120,7 +120,9 @@ class Oval extends AbstractShapeLayer implements SketchNodeFactory { .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); return Future.value(InheritedOval(this, name, - currentContext: currentContext, image: image)); + currentContext: currentContext, + image: image, + constraints: resizingConstraint)); } @override diff --git a/lib/input/sketch/entities/layers/polygon.dart b/lib/input/sketch/entities/layers/polygon.dart index 4f37ea68..65ae7f7f 100644 --- a/lib/input/sketch/entities/layers/polygon.dart +++ b/lib/input/sketch/entities/layers/polygon.dart @@ -122,7 +122,9 @@ class Polygon extends AbstractShapeLayer implements SketchNodeFactory { .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); return Future.value(InheritedPolygon(this, name, - currentContext: currentContext, image: image)); + currentContext: currentContext, + image: image, + constraints: resizingConstraint)); } @override diff --git a/lib/input/sketch/entities/layers/rectangle.dart b/lib/input/sketch/entities/layers/rectangle.dart index 18beda16..017e6747 100644 --- a/lib/input/sketch/entities/layers/rectangle.dart +++ b/lib/input/sketch/entities/layers/rectangle.dart @@ -144,6 +144,7 @@ class Rectangle extends AbstractShapeLayer 'borderColorHex': border != null ? toHex(border.color) : null, 'borderThickness': border != null ? border.thickness : null }, + constraints: resizingConstraint, )); } diff --git a/lib/input/sketch/entities/layers/shape_group.dart b/lib/input/sketch/entities/layers/shape_group.dart index bec2755e..8059e9ce 100644 --- a/lib/input/sketch/entities/layers/shape_group.dart +++ b/lib/input/sketch/entities/layers/shape_group.dart @@ -124,7 +124,9 @@ class ShapeGroup extends AbstractGroupLayer implements SketchNodeFactory { .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); return InheritedShapeGroup(this, name, - currentContext: currentContext, image: image); + currentContext: currentContext, + image: image, + constraints: resizingConstraint); } @override diff --git a/lib/input/sketch/entities/layers/shape_path.dart b/lib/input/sketch/entities/layers/shape_path.dart index 46bb995a..ea48b332 100644 --- a/lib/input/sketch/entities/layers/shape_path.dart +++ b/lib/input/sketch/entities/layers/shape_path.dart @@ -119,7 +119,9 @@ class ShapePath extends AbstractShapeLayer implements SketchNodeFactory { .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); return Future.value(InheritedShapePath(this, name, - currentContext: currentContext, image: image)); + currentContext: currentContext, + image: image, + constraints: resizingConstraint)); } @override diff --git a/lib/input/sketch/entities/layers/sketch_text.dart b/lib/input/sketch/entities/layers/sketch_text.dart index e8f279dc..1461c554 100644 --- a/lib/input/sketch/entities/layers/sketch_text.dart +++ b/lib/input/sketch/entities/layers/sketch_text.dart @@ -136,6 +136,7 @@ class SketchText extends SketchNode implements SketchNodeFactory, Text { name, Uuid().v4(), currentContext: currentContext, + constraints: resizingConstraint, )..addChild( InheritedText(this, name, currentContext: currentContext), )); @@ -201,8 +202,7 @@ class SketchText extends SketchNode implements SketchNodeFactory, Text { var attributedString; @override - set automaticallyDrawOnUnderlyingPath( - _automaticallyDrawOnUnderlyingPath) { + set automaticallyDrawOnUnderlyingPath(_automaticallyDrawOnUnderlyingPath) { // TODO: implement automaticallyDrawOnUnderlyingPath } diff --git a/lib/input/sketch/entities/layers/star.dart b/lib/input/sketch/entities/layers/star.dart index 200d485d..45e66792 100644 --- a/lib/input/sketch/entities/layers/star.dart +++ b/lib/input/sketch/entities/layers/star.dart @@ -119,8 +119,13 @@ class Star extends AbstractShapeLayer implements SketchNodeFactory { var image = await SketchAssetProcessor() .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); - return Future.value(InheritedStar(this, name, - currentContext: currentContext, image: image)); + return Future.value(InheritedStar( + this, + name, + currentContext: currentContext, + image: image, + constraints: resizingConstraint, + )); } @override diff --git a/lib/input/sketch/entities/layers/symbol_instance.dart b/lib/input/sketch/entities/layers/symbol_instance.dart index 83d699b7..745bb206 100644 --- a/lib/input/sketch/entities/layers/symbol_instance.dart +++ b/lib/input/sketch/entities/layers/symbol_instance.dart @@ -145,9 +145,13 @@ class SymbolInstance extends SketchNode @override Future interpretNode(PBContext currentContext) { - var sym = PBSharedInstanceIntermediateNode(this, symbolID, - sharedParamValues: _extractParameters(), - currentContext: currentContext); + var sym = PBSharedInstanceIntermediateNode( + this, + symbolID, + sharedParamValues: _extractParameters(), + currentContext: currentContext, + constraints: resizingConstraint, + ); return Future.value(sym); } diff --git a/lib/input/sketch/entities/layers/triangle.dart b/lib/input/sketch/entities/layers/triangle.dart index df9b6c80..2053f1d3 100644 --- a/lib/input/sketch/entities/layers/triangle.dart +++ b/lib/input/sketch/entities/layers/triangle.dart @@ -121,7 +121,9 @@ class Triangle extends AbstractShapeLayer implements SketchNodeFactory { .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); return Future.value(InheritedTriangle(this, name, - currentContext: currentContext, image: image)); + currentContext: currentContext, + image: image, + constraints: resizingConstraint)); } @override diff --git a/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart b/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart new file mode 100644 index 00000000..8823f4d2 --- /dev/null +++ b/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart @@ -0,0 +1,7 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; + +PBDLConstraints convertSketchConstraintToPBDLConstraint( + int resizingConstraint) { + var constraints = PBDLConstraints(); + return constraints; +} diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index b95bb026..60f8f78c 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -23,12 +24,11 @@ class InheritedBitmap extends PBVisualIntermediateNode String referenceImage; - InheritedBitmap( - this.originalRef, - String name, { - PBContext currentContext, - this.referenceImage, - }) : super( + InheritedBitmap(this.originalRef, String name, + {PBContext currentContext, + this.referenceImage, + PBDLConstraints constraints}) + : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), Point( @@ -38,7 +38,8 @@ class InheritedBitmap extends PBVisualIntermediateNode originalRef.boundaryRectangle.height), currentContext, name, - UUID: originalRef.UUID ?? '') { + UUID: originalRef.UUID ?? '', + constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index ee2b67d9..be188332 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -21,18 +22,16 @@ class InheritedContainer extends PBVisualIntermediateNode bool isBackgroundVisible = true; - InheritedContainer( - this.originalRef, - Point topLeftCorner, - Point bottomRightCorner, - String name, { - double alignX, - double alignY, - PBContext currentContext, - Map borderInfo, - this.isBackgroundVisible = true, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: originalRef.UUID ?? '') { + InheritedContainer(this.originalRef, Point topLeftCorner, + Point bottomRightCorner, String name, + {double alignX, + double alignY, + PBContext currentContext, + Map borderInfo, + this.isBackgroundVisible = true, + PBDLConstraints constraints}) + : super(topLeftCorner, bottomRightCorner, currentContext, name, + UUID: originalRef.UUID ?? '', constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index 1f39fb2e..93f11a24 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_pa import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -22,7 +23,7 @@ class InheritedOval extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedOval(this.originalRef, String name, - {Uint8List image, PBContext currentContext}) + {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), @@ -33,7 +34,8 @@ class InheritedOval extends PBVisualIntermediateNode originalRef.boundaryRectangle.height), currentContext, name, - UUID: originalRef.UUID ?? '') { + UUID: originalRef.UUID ?? '', + constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index 04e419b4..248a671d 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_pa import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -20,7 +21,7 @@ class InheritedPolygon extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedPolygon(this.originalRef, String name, - {Uint8List image, PBContext currentContext}) + {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), @@ -31,7 +32,8 @@ class InheritedPolygon extends PBVisualIntermediateNode originalRef.boundaryRectangle.height), currentContext, name, - UUID: originalRef.UUID ?? '') { + UUID: originalRef.UUID ?? '', + constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index 6badf7f4..f984e046 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -20,7 +21,7 @@ class InheritedShapeGroup extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedShapeGroup(this.originalRef, String name, - {Uint8List image, PBContext currentContext}) + {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), @@ -31,7 +32,8 @@ class InheritedShapeGroup extends PBVisualIntermediateNode originalRef.boundaryRectangle.height), currentContext, name, - UUID: originalRef.UUID ?? '') { + UUID: originalRef.UUID ?? '', + constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 6758df28..53a0e294 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/shape_path.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -23,7 +24,7 @@ class InheritedShapePath extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedShapePath(this.originalRef, String name, - {Uint8List image, PBContext currentContext}) + {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), @@ -34,7 +35,8 @@ class InheritedShapePath extends PBVisualIntermediateNode originalRef.boundaryRectangle.height), currentContext, name, - UUID: originalRef.UUID ?? '') { + UUID: originalRef.UUID ?? '', + constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index 3969b18e..8f532658 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_pa import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -20,7 +21,7 @@ class InheritedStar extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedStar(this.originalRef, String name, - {Uint8List image, PBContext currentContext}) + {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), @@ -31,7 +32,8 @@ class InheritedStar extends PBVisualIntermediateNode originalRef.boundaryRectangle.height), currentContext, name, - UUID: originalRef.UUID ?? '') { + UUID: originalRef.UUID ?? '', + constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 3d2cc7f4..06c35a1b 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_pa import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -20,7 +21,7 @@ class InheritedTriangle extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedTriangle(this.originalRef, String name, - {Uint8List image, PBContext currentContext}) + {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), @@ -31,7 +32,8 @@ class InheritedTriangle extends PBVisualIntermediateNode originalRef.boundaryRectangle.height), currentContext, name, - UUID: originalRef.UUID ?? '') { + UUID: originalRef.UUID ?? '', + constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 73bf4267..3c4307f1 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -21,8 +22,9 @@ class InjectedContainer extends PBVisualIntermediateNode double alignY, String color, PBContext currentContext, + PBDLConstraints constraints, }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID) { + UUID: UUID, constraints: constraints) { generator = PBContainerGenerator(); size = { diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index 7d4c91c5..395fecd4 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; /// A temporary node that must be removed @@ -16,7 +17,7 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode String get UUID => originalRef.UUID; TempGroupLayoutNode(this.originalRef, PBContext currentContext, String name, - {topLeftCorner, bottomRightCorner}) + {topLeftCorner, bottomRightCorner, PBDLConstraints constraints}) : super([], [], currentContext, name) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); @@ -46,8 +47,7 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { - assert( - false, 'Attempted to generateLayout for class type [$runtimeType]'); + assert(false, 'Attempted to generateLayout for class type [$runtimeType]'); return null; } } diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 285339dd..e2b475d7 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -38,14 +39,13 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode List overrideValues; - PBSharedInstanceIntermediateNode( - this.originalRef, - this.SYMBOL_ID, { - this.sharedParamValues, - Point topLeftCorner, - Point bottomRightCorner, - PBContext currentContext, - }) : super( + PBSharedInstanceIntermediateNode(this.originalRef, this.SYMBOL_ID, + {this.sharedParamValues, + Point topLeftCorner, + Point bottomRightCorner, + PBContext currentContext, + PBDLConstraints constraints}) + : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), Point( @@ -55,7 +55,8 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode originalRef.boundaryRectangle.height)), currentContext, originalRef.name, - UUID: originalRef.UUID) { + UUID: originalRef.UUID, + constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 455a8216..8226ac74 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -21,6 +22,8 @@ abstract class PBIntermediateNode { final String UUID; + PBDLConstraints constraints; + /// Map representing the attributes of [this]. /// The key represents the name of the attribute, while the value /// is a List representing the nodes under @@ -62,7 +65,7 @@ abstract class PBIntermediateNode { PBIntermediateNode( this.topLeftCorner, this.bottomRightCorner, this.UUID, this.name, - {this.currentContext, this.subsemantic}) { + {this.currentContext, this.subsemantic, this.constraints}) { _attributes = []; _pointCorrection(); } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart index 6e95cbf3..2a4d0f1b 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -8,9 +9,10 @@ abstract class PBVisualIntermediateNode extends PBIntermediateNode { // final String UUID; PBVisualIntermediateNode(Point topLeftCorner, Point bottomRightCorner, - PBContext currentContext, String name, {String UUID}) + PBContext currentContext, String name, + {String UUID, PBDLConstraints constraints}) : super(topLeftCorner, bottomRightCorner, UUID, name, - currentContext: currentContext); + currentContext: currentContext, constraints: constraints); void alignChild(); } diff --git a/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart new file mode 100644 index 00000000..00031b6a --- /dev/null +++ b/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart @@ -0,0 +1,9 @@ +/// Named PBDL in anticipation of the refactor where PBDL becomes the design standard. +class PBDLConstraints { + bool pinLeft; + bool pinRight; + bool pinTop; + bool pinBottom; + bool fixedHeight; + bool fixedWidth; +} From 47dffe9529c423109f5413d8be676556bf440760 Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Sun, 30 May 2021 00:27:56 -0600 Subject: [PATCH 158/404] Added Sketch BitField to PBDL Mapping --- .../helper/sketch_constraint_to_pbdl.dart | 354 +++++++++++++++++- .../entities/subclasses/pbdl_constraints.dart | 8 + 2 files changed, 361 insertions(+), 1 deletion(-) diff --git a/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart b/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart index 8823f4d2..d89b3e37 100644 --- a/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart +++ b/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart @@ -2,6 +2,358 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_co PBDLConstraints convertSketchConstraintToPBDLConstraint( int resizingConstraint) { - var constraints = PBDLConstraints(); + var constraints = sketchConstraintBitFieldToPBDLMap[resizingConstraint]; + if (constraints == null) { + print( + '[PBDL Conversion Error] We don\' support this `resizingConstraint` from Sketch.'); + } return constraints; } + +/// A map that references the Sketch Constraint Bitmap to PBDL Constraints. +/// For reference: https://www.notion.so/parabeac/2ff2c018c44644d9bba6bc4567f249c2?v=5c9a4978c96b4ee1aab8b219e3a2c006 +var sketchConstraintBitFieldToPBDLMap = { + 63: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: false, + pinBottom: false, + fixedHeight: false, + fixedWidth: false), + 18: PBDLConstraints( + pinLeft: true, + pinRight: true, + pinTop: true, + pinBottom: true, + fixedHeight: false, + fixedWidth: false), + 31: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: true, + pinBottom: false, + fixedHeight: false, + fixedWidth: false), + 27: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: true, + pinBottom: false, + fixedHeight: false, + fixedWidth: false), + 19: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: true, + pinBottom: true, + fixedHeight: false, + fixedWidth: false), + 22: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: true, + pinBottom: true, + fixedHeight: false, + fixedWidth: false), + 30: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: true, + pinBottom: false, + fixedHeight: false, + fixedWidth: false), + 26: PBDLConstraints( + pinLeft: true, + pinRight: true, + pinTop: true, + pinBottom: false, + fixedHeight: false, + fixedWidth: false), + 23: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: true, + pinBottom: true, + fixedHeight: false, + fixedWidth: false), + 59: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: false, + pinBottom: false, + fixedHeight: false, + fixedWidth: false), + 51: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: false, + pinBottom: true, + fixedHeight: false, + fixedWidth: false), + 50: PBDLConstraints( + pinLeft: true, + pinRight: true, + pinTop: false, + pinBottom: true, + fixedHeight: false, + fixedWidth: false), + 58: PBDLConstraints( + pinLeft: true, + pinRight: true, + pinTop: false, + pinBottom: false, + fixedHeight: false, + fixedWidth: false), + 55: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: false, + pinBottom: true, + fixedHeight: false, + fixedWidth: false), + 54: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: false, + pinBottom: true, + fixedHeight: false, + fixedWidth: false), + 62: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: false, + pinBottom: false, + fixedHeight: false, + fixedWidth: false), + 61: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: false, + pinBottom: false, + fixedHeight: false, + fixedWidth: true), + 29: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: true, + pinBottom: false, + fixedHeight: false, + fixedWidth: true), + 25: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: true, + pinBottom: false, + fixedHeight: false, + fixedWidth: true), + 17: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: true, + pinBottom: true, + fixedHeight: false, + fixedWidth: true), + 57: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: false, + pinBottom: false, + fixedHeight: false, + fixedWidth: true), + 49: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: false, + pinBottom: true, + fixedHeight: false, + fixedWidth: true), + 53: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: false, + pinBottom: true, + fixedHeight: false, + fixedWidth: true), + 52: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: false, + pinBottom: true, + fixedHeight: false, + fixedWidth: true), + 20: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: true, + pinBottom: true, + fixedHeight: false, + fixedWidth: true), + 60: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: false, + pinBottom: false, + fixedHeight: false, + fixedWidth: true), + 28: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: true, + pinBottom: false, + fixedHeight: false, + fixedWidth: true), + 21: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: true, + pinBottom: true, + fixedHeight: false, + fixedWidth: true), + 47: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: false, + pinBottom: false, + fixedHeight: true, + fixedWidth: false), + 15: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: true, + pinBottom: false, + fixedHeight: true, + fixedWidth: false), + 11: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: true, + pinBottom: false, + fixedHeight: true, + fixedWidth: false), + 43: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: false, + pinBottom: false, + fixedHeight: true, + fixedWidth: false), + 35: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: false, + pinBottom: true, + fixedHeight: true, + fixedWidth: false), + 34: PBDLConstraints( + pinLeft: true, + pinRight: true, + pinTop: false, + pinBottom: true, + fixedHeight: true, + fixedWidth: false), + 39: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: false, + pinBottom: true, + fixedHeight: true, + fixedWidth: false), + 38: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: false, + pinBottom: true, + fixedHeight: true, + fixedWidth: false), + 46: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: false, + pinBottom: false, + fixedHeight: true, + fixedWidth: false), + 14: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: true, + pinBottom: false, + fixedHeight: true, + fixedWidth: false), + 10: PBDLConstraints( + pinLeft: true, + pinRight: true, + pinTop: true, + pinBottom: false, + fixedHeight: true, + fixedWidth: false), + 42: PBDLConstraints( + pinLeft: true, + pinRight: true, + pinTop: false, + pinBottom: false, + fixedHeight: true, + fixedWidth: false), + 45: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: false, + pinBottom: false, + fixedHeight: true, + fixedWidth: true), + 13: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: true, + pinBottom: false, + fixedHeight: true, + fixedWidth: true), + 9: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: true, + pinBottom: false, + fixedHeight: true, + fixedWidth: true), + 41: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: false, + pinBottom: false, + fixedHeight: true, + fixedWidth: true), + 33: PBDLConstraints( + pinLeft: true, + pinRight: false, + pinTop: false, + pinBottom: true, + fixedHeight: true, + fixedWidth: true), + 37: PBDLConstraints( + pinLeft: false, + pinRight: false, + pinTop: false, + pinBottom: true, + fixedHeight: true, + fixedWidth: true), + 36: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: false, + pinBottom: true, + fixedHeight: true, + fixedWidth: true), + 44: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: false, + pinBottom: false, + fixedHeight: true, + fixedWidth: true), + 12: PBDLConstraints( + pinLeft: false, + pinRight: true, + pinTop: true, + pinBottom: false, + fixedHeight: true, + fixedWidth: true) +}; diff --git a/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart index 00031b6a..0815cfe8 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart @@ -1,5 +1,13 @@ /// Named PBDL in anticipation of the refactor where PBDL becomes the design standard. +/// Each property must be set, potentially use https://pub.dev/packages/meta to make these named parameters required. class PBDLConstraints { + PBDLConstraints( + {this.pinLeft, + this.pinRight, + this.pinTop, + this.pinBottom, + this.fixedHeight, + this.fixedWidth}); bool pinLeft; bool pinRight; bool pinTop; From 0343c3711c9d242244746ebb70bc21c46acdb843 Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Sun, 30 May 2021 08:03:02 -0600 Subject: [PATCH 159/404] Created Figma Constraints & Conversion to PBDL --- .../entities/style/figma_constraints.dart | 8 +++ .../helper/figma_constraint_to_pbdl.dart | 67 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 lib/input/figma/entities/style/figma_constraints.dart create mode 100644 lib/input/helper/figma_constraint_to_pbdl.dart diff --git a/lib/input/figma/entities/style/figma_constraints.dart b/lib/input/figma/entities/style/figma_constraints.dart new file mode 100644 index 00000000..7c5bfec7 --- /dev/null +++ b/lib/input/figma/entities/style/figma_constraints.dart @@ -0,0 +1,8 @@ +/// Defined by https://www.figma.com/plugin-docs/api/Constraints/ +class FigmaConstraints { + FigmaConstraints(this.horizontal, this.vertical); + FigmaConstraintType horizontal; + FigmaConstraintType vertical; +} + +enum FigmaConstraintType { MIN, CENTER, MAX, STRETCH, SCALE } diff --git a/lib/input/helper/figma_constraint_to_pbdl.dart b/lib/input/helper/figma_constraint_to_pbdl.dart new file mode 100644 index 00000000..46a8f94a --- /dev/null +++ b/lib/input/helper/figma_constraint_to_pbdl.dart @@ -0,0 +1,67 @@ +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; + +PBDLConstraints convertFigmaConstraintToPBDLConstraint( + FigmaConstraints figmaConstraints) { + var constraints = PBDLConstraints(); + constraints = + convertFigmaConstraint(figmaConstraints.horizontal, constraints, false); + return convertFigmaConstraint(figmaConstraints.vertical, constraints, true); +} + +/// Defined by https://www.figma.com/plugin-docs/api/Constraints/ +PBDLConstraints convertFigmaConstraint(FigmaConstraintType figmaConstraintType, + PBDLConstraints constraints, bool isVertical) { + if (figmaConstraintType == FigmaConstraintType.SCALE) { + if (isVertical) { + constraints.pinTop = false; + constraints.pinBottom = false; + constraints.fixedHeight = false; + } else { + constraints.pinLeft = false; + constraints.pinRight = false; + constraints.fixedWidth = false; + } + } else if (figmaConstraintType == FigmaConstraintType.MIN) { + if (isVertical) { + constraints.pinTop = true; + constraints.pinBottom = false; + constraints.fixedHeight = false; + } else { + constraints.pinLeft = true; + constraints.pinRight = false; + constraints.fixedWidth = false; + } + } else if (figmaConstraintType == FigmaConstraintType.MAX) { + if (isVertical) { + constraints.pinTop = false; + constraints.pinBottom = true; + constraints.fixedHeight = false; + } else { + constraints.pinLeft = false; + constraints.pinRight = true; + constraints.fixedWidth = false; + } + } else if (figmaConstraintType == FigmaConstraintType.CENTER) { + if (isVertical) { + constraints.pinTop = false; + constraints.pinBottom = false; + constraints.fixedHeight = true; + } else { + constraints.pinLeft = false; + constraints.pinRight = false; + constraints.fixedWidth = true; + } + } else if (figmaConstraintType == FigmaConstraintType.STRETCH) { + if (isVertical) { + constraints.pinTop = true; + constraints.pinBottom = true; + constraints.fixedHeight = false; + } else { + constraints.pinLeft = true; + constraints.pinRight = true; + constraints.fixedWidth = false; + } + } + return constraints; +} From 5aafb84c4dad70e7c9691fb5b9362985136e9a77 Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Sun, 30 May 2021 09:13:04 -0600 Subject: [PATCH 160/404] Added FigmaConstraints to Figma specific elements, updated FigmaConstraints to match actual API output instead of the API documentation. --- .../entities/layers/boolean_operation.dart | 1 + .../entities/layers/boolean_operation.g.dart | 4 +- .../figma/entities/layers/component.dart | 4 +- .../figma/entities/layers/component.g.dart | 5 +- lib/input/figma/entities/layers/ellipse.dart | 12 ++- .../figma/entities/layers/ellipse.g.dart | 5 +- lib/input/figma/entities/layers/frame.dart | 3 +- lib/input/figma/entities/layers/frame.g.dart | 5 +- lib/input/figma/entities/layers/group.dart | 25 ++++-- lib/input/figma/entities/layers/group.g.dart | 5 +- lib/input/figma/entities/layers/instance.dart | 5 +- .../figma/entities/layers/instance.g.dart | 5 +- lib/input/figma/entities/layers/line.dart | 5 +- lib/input/figma/entities/layers/line.g.dart | 5 +- .../figma/entities/layers/rectangle.dart | 13 ++- .../figma/entities/layers/rectangle.g.dart | 5 +- .../entities/layers/regular_polygon.dart | 12 ++- .../entities/layers/regular_polygon.g.dart | 5 +- lib/input/figma/entities/layers/slice.dart | 18 ++-- lib/input/figma/entities/layers/slice.g.dart | 5 +- lib/input/figma/entities/layers/star.dart | 5 +- lib/input/figma/entities/layers/star.g.dart | 5 +- lib/input/figma/entities/layers/text.dart | 5 +- lib/input/figma/entities/layers/text.g.dart | 5 +- lib/input/figma/entities/layers/vector.dart | 12 ++- lib/input/figma/entities/layers/vector.g.dart | 5 +- .../entities/style/figma_constraints.dart | 28 ++++++- .../entities/style/figma_constraints.g.dart | 63 ++++++++++++++ .../helper/figma_constraint_to_pbdl.dart | 84 +++++++++++-------- 29 files changed, 280 insertions(+), 79 deletions(-) create mode 100644 lib/input/figma/entities/style/figma_constraints.g.dart diff --git a/lib/input/figma/entities/layers/boolean_operation.dart b/lib/input/figma/entities/layers/boolean_operation.dart index 36a6844a..76018f2b 100644 --- a/lib/input/figma/entities/layers/boolean_operation.dart +++ b/lib/input/figma/entities/layers/boolean_operation.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/design_logic/group_node.dart'; import 'package:parabeac_core/design_logic/image.dart'; import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; import 'package:parabeac_core/input/figma/entities/style/figma_style.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; diff --git a/lib/input/figma/entities/layers/boolean_operation.g.dart b/lib/input/figma/entities/layers/boolean_operation.g.dart index fce0f57d..469dde06 100644 --- a/lib/input/figma/entities/layers/boolean_operation.g.dart +++ b/lib/input/figma/entities/layers/boolean_operation.g.dart @@ -30,7 +30,9 @@ BooleanOperation _$BooleanOperationFromJson(Map json) { ..sharedPluginData = json['sharedPluginData'] ..isVisible = json['visible'] as bool ?? true ..layoutAlign = json['layoutAlign'] as String - ..constraints = json['constraints'] + ..constraints = json['constraints'] == null + ? null + : FigmaConstraints.fromJson(json['constraints'] as Map) ..size = json['size'] ..strokes = json['strokes'] ..strokeWeight = (json['strokeWeight'] as num)?.toDouble() diff --git a/lib/input/figma/entities/layers/component.dart b/lib/input/figma/entities/layers/component.dart index 345f6218..6bdf0d96 100644 --- a/lib/input/figma/entities/layers/component.dart +++ b/lib/input/figma/entities/layers/component.dart @@ -5,6 +5,8 @@ import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.d import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; import 'package:parabeac_core/input/figma/entities/layers/frame.dart'; import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; @@ -33,7 +35,7 @@ class Component extends FigmaFrame strokeWeight, strokeAlign, cornerRadius, - constraints, + FigmaConstraints constraints, layoutAlign, size, horizontalPadding, diff --git a/lib/input/figma/entities/layers/component.g.dart b/lib/input/figma/entities/layers/component.g.dart index 0a4bbc51..76c754bd 100644 --- a/lib/input/figma/entities/layers/component.g.dart +++ b/lib/input/figma/entities/layers/component.g.dart @@ -20,7 +20,10 @@ Component _$ComponentFromJson(Map json) { strokeWeight: json['strokeWeight'], strokeAlign: json['strokeAlign'], cornerRadius: json['cornerRadius'], - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), layoutAlign: json['layoutAlign'], size: json['size'], horizontalPadding: json['horizontalPadding'], diff --git a/lib/input/figma/entities/layers/ellipse.dart b/lib/input/figma/entities/layers/ellipse.dart index 7afe254b..03555e73 100644 --- a/lib/input/figma/entities/layers/ellipse.dart +++ b/lib/input/figma/entities/layers/ellipse.dart @@ -2,7 +2,9 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/design_logic/image.dart'; import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -35,7 +37,7 @@ class FigmaEllipse extends FigmaVector sharedPluginData, style, layoutAlign, - constraints, + FigmaConstraints constraints, Frame boundaryRectangle, size, this.fills, @@ -80,8 +82,12 @@ class FigmaEllipse extends FigmaVector @override Future interpretNode(PBContext currentContext) async { imageReference = FigmaAssetProcessor().processImage(UUID); - return Future.value( - InheritedBitmap(this, name, currentContext: currentContext)); + return Future.value(InheritedBitmap( + this, + name, + currentContext: currentContext, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), + )); } @override diff --git a/lib/input/figma/entities/layers/ellipse.g.dart b/lib/input/figma/entities/layers/ellipse.g.dart index 4b942289..cb6e0515 100644 --- a/lib/input/figma/entities/layers/ellipse.g.dart +++ b/lib/input/figma/entities/layers/ellipse.g.dart @@ -14,7 +14,10 @@ FigmaEllipse _$FigmaEllipseFromJson(Map json) { sharedPluginData: json['sharedPluginData'], style: json['style'], layoutAlign: json['layoutAlign'], - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), boundaryRectangle: json['absoluteBoundingBox'] == null ? null : Frame.fromJson(json['absoluteBoundingBox'] as Map), diff --git a/lib/input/figma/entities/layers/frame.dart b/lib/input/figma/entities/layers/frame.dart index 4de96d9a..8625bdde 100644 --- a/lib/input/figma/entities/layers/frame.dart +++ b/lib/input/figma/entities/layers/frame.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.d import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; import 'package:parabeac_core/input/figma/entities/layers/group.dart'; import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; import 'package:parabeac_core/input/figma/helper/style_extractor.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -42,7 +43,7 @@ class FigmaFrame extends FigmaNode double cornerRadius; - var constraints; + FigmaConstraints constraints; String layoutAlign; diff --git a/lib/input/figma/entities/layers/frame.g.dart b/lib/input/figma/entities/layers/frame.g.dart index f0538714..087da5fd 100644 --- a/lib/input/figma/entities/layers/frame.g.dart +++ b/lib/input/figma/entities/layers/frame.g.dart @@ -20,7 +20,10 @@ FigmaFrame _$FigmaFrameFromJson(Map json) { strokeWeight: (json['strokeWeight'] as num)?.toDouble(), strokeAlign: json['strokeAlign'] as String, cornerRadius: (json['cornerRadius'] as num)?.toDouble(), - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), layoutAlign: json['layoutAlign'] as String, size: json['size'], horizontalPadding: (json['horizontalPadding'] as num)?.toDouble(), diff --git a/lib/input/figma/entities/layers/group.dart b/lib/input/figma/entities/layers/group.dart index 3b0c398b..5c3bd260 100644 --- a/lib/input/figma/entities/layers/group.dart +++ b/lib/input/figma/entities/layers/group.dart @@ -7,7 +7,9 @@ import 'package:parabeac_core/input/figma/entities/layers/frame.dart'; import 'package:parabeac_core/input/figma/entities/layers/text.dart'; import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; @@ -45,7 +47,7 @@ class Group extends FigmaFrame implements AbstractFigmaNodeFactory, Image { strokeWeight, strokeAlign, cornerRadius, - constraints, + FigmaConstraints constraints, layoutAlign, size, horizontalPadding, @@ -112,13 +114,22 @@ class Group extends FigmaFrame implements AbstractFigmaNodeFactory, Image { children.clear(); - return Future.value( - InheritedBitmap(this, name, currentContext: currentContext)); + return Future.value(InheritedBitmap( + this, + name, + currentContext: currentContext, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), + )); } - return Future.value(TempGroupLayoutNode(this, currentContext, name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height))); + return Future.value(TempGroupLayoutNode( + this, + currentContext, + name, + topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), + bottomRightCorner: Point(boundaryRectangle.x + boundaryRectangle.width, + boundaryRectangle.y + boundaryRectangle.height), + constraints: convertFigmaConstraintToPBDLConstraint(constraints), + )); } bool areAllVectors() { diff --git a/lib/input/figma/entities/layers/group.g.dart b/lib/input/figma/entities/layers/group.g.dart index 937aca41..456174a5 100644 --- a/lib/input/figma/entities/layers/group.g.dart +++ b/lib/input/figma/entities/layers/group.g.dart @@ -20,7 +20,10 @@ Group _$GroupFromJson(Map json) { strokeWeight: json['strokeWeight'], strokeAlign: json['strokeAlign'], cornerRadius: json['cornerRadius'], - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), layoutAlign: json['layoutAlign'], size: json['size'], horizontalPadding: json['horizontalPadding'], diff --git a/lib/input/figma/entities/layers/instance.dart b/lib/input/figma/entities/layers/instance.dart index 6c5d419b..01b6b8ec 100644 --- a/lib/input/figma/entities/layers/instance.dart +++ b/lib/input/figma/entities/layers/instance.dart @@ -4,6 +4,8 @@ import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.d import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; import 'package:parabeac_core/input/figma/entities/layers/frame.dart'; import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/objects/override_value.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; @@ -39,7 +41,7 @@ class Instance extends FigmaFrame strokeWeight, strokeAlign, cornerRadius, - constraints, + FigmaConstraints constraints, layoutAlign, size, horizontalPadding, @@ -98,6 +100,7 @@ class Instance extends FigmaFrame componentId, sharedParamValues: [], currentContext: currentContext, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), ); return Future.value(sym); } diff --git a/lib/input/figma/entities/layers/instance.g.dart b/lib/input/figma/entities/layers/instance.g.dart index 2fe12f43..e9ff65e3 100644 --- a/lib/input/figma/entities/layers/instance.g.dart +++ b/lib/input/figma/entities/layers/instance.g.dart @@ -20,7 +20,10 @@ Instance _$InstanceFromJson(Map json) { strokeWeight: json['strokeWeight'], strokeAlign: json['strokeAlign'], cornerRadius: json['cornerRadius'], - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), layoutAlign: json['layoutAlign'], size: json['size'], horizontalPadding: json['horizontalPadding'], diff --git a/lib/input/figma/entities/layers/line.dart b/lib/input/figma/entities/layers/line.dart index 6ad98782..3804ef74 100644 --- a/lib/input/figma/entities/layers/line.dart +++ b/lib/input/figma/entities/layers/line.dart @@ -1,6 +1,8 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -24,7 +26,7 @@ class FigmaLine extends FigmaVector implements AbstractFigmaNodeFactory { sharedPluginData, style, layoutAlign, - constraints, + FigmaConstraints constraints, Frame boundaryRectangle, size, fills, @@ -75,6 +77,7 @@ class FigmaLine extends FigmaVector implements AbstractFigmaNodeFactory { boundaryRectangle.y + boundaryRectangle.height, ), name, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), )); } diff --git a/lib/input/figma/entities/layers/line.g.dart b/lib/input/figma/entities/layers/line.g.dart index 0f2f39ed..4d685a90 100644 --- a/lib/input/figma/entities/layers/line.g.dart +++ b/lib/input/figma/entities/layers/line.g.dart @@ -14,7 +14,10 @@ FigmaLine _$FigmaLineFromJson(Map json) { sharedPluginData: json['sharedPluginData'], style: json['style'], layoutAlign: json['layoutAlign'], - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), boundaryRectangle: json['absoluteBoundingBox'] == null ? null : Frame.fromJson(json['absoluteBoundingBox'] as Map), diff --git a/lib/input/figma/entities/layers/rectangle.dart b/lib/input/figma/entities/layers/rectangle.dart index 251aa9d9..0efaa3c2 100644 --- a/lib/input/figma/entities/layers/rectangle.dart +++ b/lib/input/figma/entities/layers/rectangle.dart @@ -3,8 +3,10 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/design_logic/pb_border.dart'; import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/input/figma/helper/style_extractor.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; @@ -31,7 +33,7 @@ class FigmaRectangle extends FigmaVector sharedPluginData, style, layoutAlign, - constraints, + FigmaConstraints constraints, Frame boundaryRectangle, size, strokes, @@ -97,8 +99,12 @@ class FigmaRectangle extends FigmaVector if (fillsMap != null && fillsMap['type'] == 'IMAGE') { imageReference = FigmaAssetProcessor().processImage(UUID); - return Future.value( - InheritedBitmap(this, name, currentContext: currentContext)); + return Future.value(InheritedBitmap( + this, + name, + currentContext: currentContext, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), + )); } PBBorder border; for (var b in style?.borders?.reversed ?? []) { @@ -123,6 +129,7 @@ class FigmaRectangle extends FigmaVector ? toHex(style.borders[0].color) : null }, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), )); } diff --git a/lib/input/figma/entities/layers/rectangle.g.dart b/lib/input/figma/entities/layers/rectangle.g.dart index 213f9c09..055aa26e 100644 --- a/lib/input/figma/entities/layers/rectangle.g.dart +++ b/lib/input/figma/entities/layers/rectangle.g.dart @@ -15,7 +15,10 @@ FigmaRectangle _$FigmaRectangleFromJson(Map json) { sharedPluginData: json['sharedPluginData'], style: json['style'], layoutAlign: json['layoutAlign'], - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), boundaryRectangle: json['absoluteBoundingBox'] == null ? null : Frame.fromJson(json['absoluteBoundingBox'] as Map), diff --git a/lib/input/figma/entities/layers/regular_polygon.dart b/lib/input/figma/entities/layers/regular_polygon.dart index ff2a7b23..8f7616c5 100644 --- a/lib/input/figma/entities/layers/regular_polygon.dart +++ b/lib/input/figma/entities/layers/regular_polygon.dart @@ -1,7 +1,9 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -25,7 +27,7 @@ class FigmaRegularPolygon extends FigmaVector sharedPluginData, style, layoutAlign, - constraints, + FigmaConstraints constraints, Frame boundaryRectangle, size, fills, @@ -70,8 +72,12 @@ class FigmaRegularPolygon extends FigmaVector Future interpretNode(PBContext currentContext) { imageReference = FigmaAssetProcessor().processImage(UUID); - return Future.value( - InheritedBitmap(this, name, currentContext: currentContext)); + return Future.value(InheritedBitmap( + this, + name, + currentContext: currentContext, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), + )); } @override diff --git a/lib/input/figma/entities/layers/regular_polygon.g.dart b/lib/input/figma/entities/layers/regular_polygon.g.dart index c5a51e3b..80fdcf2c 100644 --- a/lib/input/figma/entities/layers/regular_polygon.g.dart +++ b/lib/input/figma/entities/layers/regular_polygon.g.dart @@ -14,7 +14,10 @@ FigmaRegularPolygon _$FigmaRegularPolygonFromJson(Map json) { sharedPluginData: json['sharedPluginData'], style: json['style'], layoutAlign: json['layoutAlign'], - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), boundaryRectangle: json['absoluteBoundingBox'] == null ? null : Frame.fromJson(json['absoluteBoundingBox'] as Map), diff --git a/lib/input/figma/entities/layers/slice.dart b/lib/input/figma/entities/layers/slice.dart index 7590832d..136b0dde 100644 --- a/lib/input/figma/entities/layers/slice.dart +++ b/lib/input/figma/entities/layers/slice.dart @@ -1,5 +1,7 @@ import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -22,7 +24,7 @@ class FigmaSlice extends FigmaNode implements FigmaNodeFactory { String layoutAlign; - var constraints; + FigmaConstraints constraints; @override @JsonKey(name: 'absoluteBoundingBox') @@ -67,12 +69,14 @@ class FigmaSlice extends FigmaNode implements FigmaNodeFactory { @override Future interpretNode(PBContext currentContext) { return Future.value(InheritedContainer( - this, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - name, - currentContext: currentContext)); + this, + Point(boundaryRectangle.x, boundaryRectangle.y), + Point(boundaryRectangle.x + boundaryRectangle.width, + boundaryRectangle.y + boundaryRectangle.height), + name, + currentContext: currentContext, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), + )); } @override diff --git a/lib/input/figma/entities/layers/slice.g.dart b/lib/input/figma/entities/layers/slice.g.dart index 5d831502..1ec6997e 100644 --- a/lib/input/figma/entities/layers/slice.g.dart +++ b/lib/input/figma/entities/layers/slice.g.dart @@ -13,7 +13,10 @@ FigmaSlice _$FigmaSliceFromJson(Map json) { pluginData: json['pluginData'], sharedPluginData: json['sharedPluginData'], layoutAlign: json['layoutAlign'] as String, - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), boundaryRectangle: json['absoluteBoundingBox'] == null ? null : Frame.fromJson(json['absoluteBoundingBox'] as Map), diff --git a/lib/input/figma/entities/layers/star.dart b/lib/input/figma/entities/layers/star.dart index 6dbe4edb..4a6453a9 100644 --- a/lib/input/figma/entities/layers/star.dart +++ b/lib/input/figma/entities/layers/star.dart @@ -1,7 +1,9 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -24,7 +26,7 @@ class FigmaStar extends FigmaVector implements AbstractFigmaNodeFactory { sharedPluginData, style, layoutAlign, - constraints, + FigmaConstraints constraints, Frame boundaryRectangle, size, fills, @@ -73,6 +75,7 @@ class FigmaStar extends FigmaVector implements AbstractFigmaNodeFactory { name, currentContext: currentContext, referenceImage: imageReference, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), )); } diff --git a/lib/input/figma/entities/layers/star.g.dart b/lib/input/figma/entities/layers/star.g.dart index c0b0ed5b..d248f259 100644 --- a/lib/input/figma/entities/layers/star.g.dart +++ b/lib/input/figma/entities/layers/star.g.dart @@ -14,7 +14,10 @@ FigmaStar _$FigmaStarFromJson(Map json) { sharedPluginData: json['sharedPluginData'], style: json['style'], layoutAlign: json['layoutAlign'], - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), boundaryRectangle: json['absoluteBoundingBox'] == null ? null : Frame.fromJson(json['absoluteBoundingBox'] as Map), diff --git a/lib/input/figma/entities/layers/text.dart b/lib/input/figma/entities/layers/text.dart index 9569e13d..652ae26e 100644 --- a/lib/input/figma/entities/layers/text.dart +++ b/lib/input/figma/entities/layers/text.dart @@ -3,8 +3,10 @@ import 'package:parabeac_core/design_logic/pb_style.dart'; import 'package:parabeac_core/design_logic/text.dart'; import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; import 'package:parabeac_core/input/figma/entities/style/figma_style.dart'; import 'package:parabeac_core/input/figma/helper/style_extractor.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; @@ -29,7 +31,7 @@ class FigmaText extends FigmaVector implements AbstractFigmaNodeFactory, Text { sharedPluginData, FigmaStyle this.style, layoutAlign, - constraints, + FigmaConstraints constraints, Frame boundaryRectangle, size, fills, @@ -98,6 +100,7 @@ class FigmaText extends FigmaVector implements AbstractFigmaNodeFactory, Text { name, currentContext: currentContext, isBackgroundVisible: style.backgroundColor != null, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), )..addChild( InheritedText(this, name, currentContext: currentContext), )); diff --git a/lib/input/figma/entities/layers/text.g.dart b/lib/input/figma/entities/layers/text.g.dart index 0a881c62..7a1c2c7b 100644 --- a/lib/input/figma/entities/layers/text.g.dart +++ b/lib/input/figma/entities/layers/text.g.dart @@ -16,7 +16,10 @@ FigmaText _$FigmaTextFromJson(Map json) { ? null : FigmaStyle.fromJson(json['style'] as Map), layoutAlign: json['layoutAlign'], - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), boundaryRectangle: json['absoluteBoundingBox'] == null ? null : Frame.fromJson(json['absoluteBoundingBox'] as Map), diff --git a/lib/input/figma/entities/layers/vector.dart b/lib/input/figma/entities/layers/vector.dart index 93383fbd..b4034965 100644 --- a/lib/input/figma/entities/layers/vector.dart +++ b/lib/input/figma/entities/layers/vector.dart @@ -3,8 +3,10 @@ import 'package:parabeac_core/design_logic/image.dart'; import 'package:parabeac_core/design_logic/pb_style.dart'; import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; +import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; import 'package:parabeac_core/input/figma/entities/style/figma_style.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; +import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -24,7 +26,7 @@ class FigmaVector extends FigmaNode implements FigmaNodeFactory, Image { String layoutAlign; - var constraints; + FigmaConstraints constraints; @override @JsonKey(name: 'absoluteBoundingBox') @@ -92,8 +94,12 @@ class FigmaVector extends FigmaNode implements FigmaNodeFactory, Image { Future interpretNode(PBContext currentContext) async { imageReference = FigmaAssetProcessor().processImage(UUID); - return Future.value( - InheritedBitmap(this, name, currentContext: currentContext)); + return Future.value(InheritedBitmap( + this, + name, + currentContext: currentContext, + constraints: convertFigmaConstraintToPBDLConstraint(constraints), + )); } @override diff --git a/lib/input/figma/entities/layers/vector.g.dart b/lib/input/figma/entities/layers/vector.g.dart index c99195ba..1efb36a7 100644 --- a/lib/input/figma/entities/layers/vector.g.dart +++ b/lib/input/figma/entities/layers/vector.g.dart @@ -16,7 +16,10 @@ FigmaVector _$FigmaVectorFromJson(Map json) { ? null : FigmaStyle.fromJson(json['style'] as Map), layoutAlign: json['layoutAlign'] as String, - constraints: json['constraints'], + constraints: json['constraints'] == null + ? null + : FigmaConstraints.fromJson( + json['constraints'] as Map), boundaryRectangle: json['absoluteBoundingBox'] == null ? null : Frame.fromJson(json['absoluteBoundingBox'] as Map), diff --git a/lib/input/figma/entities/style/figma_constraints.dart b/lib/input/figma/entities/style/figma_constraints.dart index 7c5bfec7..54e7c1ae 100644 --- a/lib/input/figma/entities/style/figma_constraints.dart +++ b/lib/input/figma/entities/style/figma_constraints.dart @@ -1,8 +1,34 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'figma_constraints.g.dart'; + /// Defined by https://www.figma.com/plugin-docs/api/Constraints/ +@JsonSerializable(nullable: true) class FigmaConstraints { FigmaConstraints(this.horizontal, this.vertical); FigmaConstraintType horizontal; FigmaConstraintType vertical; + + factory FigmaConstraints.fromJson(Map json) => + _$FigmaConstraintsFromJson(json); + Map toJson() => _$FigmaConstraintsToJson(this); } -enum FigmaConstraintType { MIN, CENTER, MAX, STRETCH, SCALE } +enum FigmaConstraintType { + @JsonValue('CENTER') + CENTER, + @JsonValue('TOP_BOTTOM') + TOP_BOTTOM, + @JsonValue('LEFT_RIGHT') + LEFT_RIGHT, + @JsonValue('SCALE') + SCALE, + @JsonValue('TOP') + TOP, + @JsonValue('BOTTOM') + BOTTOM, + @JsonValue('RIGHT') + RIGHT, + @JsonValue('LEFT') + LEFT +} diff --git a/lib/input/figma/entities/style/figma_constraints.g.dart b/lib/input/figma/entities/style/figma_constraints.g.dart new file mode 100644 index 00000000..edabeab4 --- /dev/null +++ b/lib/input/figma/entities/style/figma_constraints.g.dart @@ -0,0 +1,63 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'figma_constraints.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +FigmaConstraints _$FigmaConstraintsFromJson(Map json) { + return FigmaConstraints( + _$enumDecodeNullable(_$FigmaConstraintTypeEnumMap, json['horizontal']), + _$enumDecodeNullable(_$FigmaConstraintTypeEnumMap, json['vertical']), + ); +} + +Map _$FigmaConstraintsToJson(FigmaConstraints instance) => + { + 'horizontal': _$FigmaConstraintTypeEnumMap[instance.horizontal], + 'vertical': _$FigmaConstraintTypeEnumMap[instance.vertical], + }; + +T _$enumDecode( + Map enumValues, + dynamic source, { + T unknownValue, +}) { + if (source == null) { + throw ArgumentError('A value must be provided. Supported values: ' + '${enumValues.values.join(', ')}'); + } + + final value = enumValues.entries + .singleWhere((e) => e.value == source, orElse: () => null) + ?.key; + + if (value == null && unknownValue == null) { + throw ArgumentError('`$source` is not one of the supported values: ' + '${enumValues.values.join(', ')}'); + } + return value ?? unknownValue; +} + +T _$enumDecodeNullable( + Map enumValues, + dynamic source, { + T unknownValue, +}) { + if (source == null) { + return null; + } + return _$enumDecode(enumValues, source, unknownValue: unknownValue); +} + +const _$FigmaConstraintTypeEnumMap = { + FigmaConstraintType.CENTER: 'CENTER', + FigmaConstraintType.TOP_BOTTOM: 'TOP_BOTTOM', + FigmaConstraintType.LEFT_RIGHT: 'LEFT_RIGHT', + FigmaConstraintType.SCALE: 'SCALE', + FigmaConstraintType.TOP: 'TOP', + FigmaConstraintType.BOTTOM: 'BOTTOM', + FigmaConstraintType.RIGHT: 'RIGHT', + FigmaConstraintType.LEFT: 'LEFT', +}; diff --git a/lib/input/helper/figma_constraint_to_pbdl.dart b/lib/input/helper/figma_constraint_to_pbdl.dart index 46a8f94a..c11fdb8d 100644 --- a/lib/input/helper/figma_constraint_to_pbdl.dart +++ b/lib/input/helper/figma_constraint_to_pbdl.dart @@ -5,12 +5,12 @@ PBDLConstraints convertFigmaConstraintToPBDLConstraint( FigmaConstraints figmaConstraints) { var constraints = PBDLConstraints(); constraints = - convertFigmaConstraint(figmaConstraints.horizontal, constraints, false); - return convertFigmaConstraint(figmaConstraints.vertical, constraints, true); + _convertFigmaConstraint(figmaConstraints.horizontal, constraints, false); + return _convertFigmaConstraint(figmaConstraints.vertical, constraints, true); } /// Defined by https://www.figma.com/plugin-docs/api/Constraints/ -PBDLConstraints convertFigmaConstraint(FigmaConstraintType figmaConstraintType, +PBDLConstraints _convertFigmaConstraint(FigmaConstraintType figmaConstraintType, PBDLConstraints constraints, bool isVertical) { if (figmaConstraintType == FigmaConstraintType.SCALE) { if (isVertical) { @@ -22,26 +22,22 @@ PBDLConstraints convertFigmaConstraint(FigmaConstraintType figmaConstraintType, constraints.pinRight = false; constraints.fixedWidth = false; } - } else if (figmaConstraintType == FigmaConstraintType.MIN) { - if (isVertical) { - constraints.pinTop = true; - constraints.pinBottom = false; - constraints.fixedHeight = false; - } else { - constraints.pinLeft = true; - constraints.pinRight = false; - constraints.fixedWidth = false; - } - } else if (figmaConstraintType == FigmaConstraintType.MAX) { - if (isVertical) { - constraints.pinTop = false; - constraints.pinBottom = true; - constraints.fixedHeight = false; - } else { - constraints.pinLeft = false; - constraints.pinRight = true; - constraints.fixedWidth = false; - } + } else if (figmaConstraintType == FigmaConstraintType.TOP) { + constraints.pinTop = true; + constraints.pinBottom = false; + constraints.fixedHeight = false; + } else if (figmaConstraintType == FigmaConstraintType.LEFT) { + constraints.pinLeft = true; + constraints.pinRight = false; + constraints.fixedWidth = false; + } else if (figmaConstraintType == FigmaConstraintType.RIGHT) { + constraints.pinLeft = false; + constraints.pinRight = true; + constraints.fixedWidth = false; + } else if (figmaConstraintType == FigmaConstraintType.BOTTOM) { + constraints.pinTop = false; + constraints.pinBottom = true; + constraints.fixedHeight = false; } else if (figmaConstraintType == FigmaConstraintType.CENTER) { if (isVertical) { constraints.pinTop = false; @@ -52,16 +48,38 @@ PBDLConstraints convertFigmaConstraint(FigmaConstraintType figmaConstraintType, constraints.pinRight = false; constraints.fixedWidth = true; } - } else if (figmaConstraintType == FigmaConstraintType.STRETCH) { - if (isVertical) { - constraints.pinTop = true; - constraints.pinBottom = true; - constraints.fixedHeight = false; - } else { - constraints.pinLeft = true; - constraints.pinRight = true; - constraints.fixedWidth = false; - } + } else if (figmaConstraintType == FigmaConstraintType.TOP_BOTTOM) { + constraints.pinTop = true; + constraints.pinBottom = true; + constraints.fixedHeight = false; + } else if (figmaConstraintType == FigmaConstraintType.LEFT_RIGHT) { + constraints.pinLeft = true; + constraints.pinRight = true; + constraints.fixedWidth = false; + } else { + print( + 'We currently do not support Figma Constraint Type: ${figmaConstraintType}'); } return constraints; } + +// } else if (figmaConstraintType == FigmaConstraintType.MIN) { +// if (isVertical) { +// constraints.pinTop = true; +// constraints.pinBottom = false; +// constraints.fixedHeight = false; +// } else { +// constraints.pinLeft = true; +// constraints.pinRight = false; +// constraints.fixedWidth = false; +// } +// } else if (figmaConstraintType == FigmaConstraintType.MAX) { +// if (isVertical) { +// constraints.pinTop = false; +// constraints.pinBottom = true; +// constraints.fixedHeight = false; +// } else { +// constraints.pinLeft = false; +// constraints.pinRight = true; +// constraints.fixedWidth = false; +// } From 034524d81a951d044ff76353830469d7c941bc71 Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Sun, 30 May 2021 19:21:15 -0600 Subject: [PATCH 161/404] Fixed Sketch Constraint Input --- lib/input/sketch/entities/layers/abstract_layer.dart | 2 +- lib/input/sketch/entities/layers/oval.dart | 4 +++- lib/input/sketch/entities/layers/polygon.dart | 4 +++- lib/input/sketch/entities/layers/rectangle.dart | 3 ++- lib/input/sketch/entities/layers/shape_group.dart | 4 +++- lib/input/sketch/entities/layers/shape_path.dart | 4 +++- lib/input/sketch/entities/layers/sketch_text.dart | 6 ++++-- lib/input/sketch/entities/layers/star.dart | 3 ++- lib/input/sketch/entities/layers/symbol_instance.dart | 3 ++- lib/input/sketch/entities/layers/triangle.dart | 4 +++- 10 files changed, 26 insertions(+), 11 deletions(-) diff --git a/lib/input/sketch/entities/layers/abstract_layer.dart b/lib/input/sketch/entities/layers/abstract_layer.dart index 22077cf8..7a69313d 100644 --- a/lib/input/sketch/entities/layers/abstract_layer.dart +++ b/lib/input/sketch/entities/layers/abstract_layer.dart @@ -33,7 +33,7 @@ abstract class SketchNode implements DesignNode { @override String name; final bool nameIsFixed; - final dynamic resizingConstraint; + final int resizingConstraint; final dynamic resizingType; final num rotation; final dynamic sharedStyleID; diff --git a/lib/input/sketch/entities/layers/oval.dart b/lib/input/sketch/entities/layers/oval.dart index e6456b59..7010d028 100644 --- a/lib/input/sketch/entities/layers/oval.dart +++ b/lib/input/sketch/entities/layers/oval.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_oval.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -122,7 +123,8 @@ class Oval extends AbstractShapeLayer implements SketchNodeFactory { return Future.value(InheritedOval(this, name, currentContext: currentContext, image: image, - constraints: resizingConstraint)); + constraints: + convertSketchConstraintToPBDLConstraint(resizingConstraint))); } @override diff --git a/lib/input/sketch/entities/layers/polygon.dart b/lib/input/sketch/entities/layers/polygon.dart index 65ae7f7f..0d407f68 100644 --- a/lib/input/sketch/entities/layers/polygon.dart +++ b/lib/input/sketch/entities/layers/polygon.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_polygon.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -124,7 +125,8 @@ class Polygon extends AbstractShapeLayer implements SketchNodeFactory { return Future.value(InheritedPolygon(this, name, currentContext: currentContext, image: image, - constraints: resizingConstraint)); + constraints: + convertSketchConstraintToPBDLConstraint(resizingConstraint))); } @override diff --git a/lib/input/sketch/entities/layers/rectangle.dart b/lib/input/sketch/entities/layers/rectangle.dart index 017e6747..b0cacfb1 100644 --- a/lib/input/sketch/entities/layers/rectangle.dart +++ b/lib/input/sketch/entities/layers/rectangle.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/border.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -144,7 +145,7 @@ class Rectangle extends AbstractShapeLayer 'borderColorHex': border != null ? toHex(border.color) : null, 'borderThickness': border != null ? border.thickness : null }, - constraints: resizingConstraint, + constraints: convertSketchConstraintToPBDLConstraint(resizingConstraint), )); } diff --git a/lib/input/sketch/entities/layers/shape_group.dart b/lib/input/sketch/entities/layers/shape_group.dart index 8059e9ce..82b4d2d8 100644 --- a/lib/input/sketch/entities/layers/shape_group.dart +++ b/lib/input/sketch/entities/layers/shape_group.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -126,7 +127,8 @@ class ShapeGroup extends AbstractGroupLayer implements SketchNodeFactory { return InheritedShapeGroup(this, name, currentContext: currentContext, image: image, - constraints: resizingConstraint); + constraints: + convertSketchConstraintToPBDLConstraint(resizingConstraint)); } @override diff --git a/lib/input/sketch/entities/layers/shape_path.dart b/lib/input/sketch/entities/layers/shape_path.dart index ea48b332..a06b7388 100644 --- a/lib/input/sketch/entities/layers/shape_path.dart +++ b/lib/input/sketch/entities/layers/shape_path.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -121,7 +122,8 @@ class ShapePath extends AbstractShapeLayer implements SketchNodeFactory { return Future.value(InheritedShapePath(this, name, currentContext: currentContext, image: image, - constraints: resizingConstraint)); + constraints: + convertSketchConstraintToPBDLConstraint(resizingConstraint))); } @override diff --git a/lib/input/sketch/entities/layers/sketch_text.dart b/lib/input/sketch/entities/layers/sketch_text.dart index 1461c554..4dae1edc 100644 --- a/lib/input/sketch/entities/layers/sketch_text.dart +++ b/lib/input/sketch/entities/layers/sketch_text.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -74,7 +75,7 @@ class SketchText extends SketchNode implements SketchNodeFactory, Text { layerListExpandedType, String name, bool nameIsFixed, - resizingConstraint, + int resizingConstraint, resizingType, double rotation, sharedStyleID, @@ -136,7 +137,8 @@ class SketchText extends SketchNode implements SketchNodeFactory, Text { name, Uuid().v4(), currentContext: currentContext, - constraints: resizingConstraint, + constraints: + convertSketchConstraintToPBDLConstraint(resizingConstraint), )..addChild( InheritedText(this, name, currentContext: currentContext), )); diff --git a/lib/input/sketch/entities/layers/star.dart b/lib/input/sketch/entities/layers/star.dart index 45e66792..878abd25 100644 --- a/lib/input/sketch/entities/layers/star.dart +++ b/lib/input/sketch/entities/layers/star.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_star.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -124,7 +125,7 @@ class Star extends AbstractShapeLayer implements SketchNodeFactory { name, currentContext: currentContext, image: image, - constraints: resizingConstraint, + constraints: convertSketchConstraintToPBDLConstraint(resizingConstraint), )); } diff --git a/lib/input/sketch/entities/layers/symbol_instance.dart b/lib/input/sketch/entities/layers/symbol_instance.dart index 745bb206..97a9a627 100644 --- a/lib/input/sketch/entities/layers/symbol_instance.dart +++ b/lib/input/sketch/entities/layers/symbol_instance.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/objects/override_value.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -150,7 +151,7 @@ class SymbolInstance extends SketchNode symbolID, sharedParamValues: _extractParameters(), currentContext: currentContext, - constraints: resizingConstraint, + constraints: convertSketchConstraintToPBDLConstraint(resizingConstraint), ); return Future.value(sym); } diff --git a/lib/input/sketch/entities/layers/triangle.dart b/lib/input/sketch/entities/layers/triangle.dart index 2053f1d3..d6db623c 100644 --- a/lib/input/sketch/entities/layers/triangle.dart +++ b/lib/input/sketch/entities/layers/triangle.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_triangle.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -123,7 +124,8 @@ class Triangle extends AbstractShapeLayer implements SketchNodeFactory { return Future.value(InheritedTriangle(this, name, currentContext: currentContext, image: image, - constraints: resizingConstraint)); + constraints: + convertSketchConstraintToPBDLConstraint(resizingConstraint))); } @override From e1f4dc38ad4ab04fb3700602497c4a46531824a5 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sat, 29 May 2021 20:46:43 -0700 Subject: [PATCH 162/404] Fixing upper case letter for default OnGesture() --- .../middleware/state_management/utils/middleware_utils.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 0d189592..a6ad2f69 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -81,7 +81,7 @@ class MiddlewareUtils { ${defaultStateName}(){} // default provider event handler for gestures. - void onGesture() { + void OnGesture() { } void setCurrentWidget(Widget currentWidget) { From 1f8fc269e79c010f070138937bf29c4c059e79cd Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sun, 30 May 2021 14:51:02 -0700 Subject: [PATCH 163/404] Do not overwrite the model files if they exist as use could have modified them --- .../provider_file_structure_strategy.dart | 9 ++++++--- .../riverpod_file_structure_strategy.dart | 10 +++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart index 3752095a..6894917d 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart @@ -28,8 +28,11 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { } void writeProviderModelFile(String code, String fileName) { - super - .pageWriter - .write(code, '${_modelsPath}${fileName}.dart'); // Removed .g + + if (!File('$_modelsPath$fileName.dart').existsSync()) { + super + .pageWriter + .write(code, '$_modelsPath$fileName.dart'); // Removed .g + } } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart index e7cb449c..6442db57 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart @@ -32,8 +32,12 @@ class RiverpodFileStructureStrategy extends FileStructureStrategy { } void writeRiverpodModelFile(String code, String fileName) { - super - .pageWriter - .write(code, '${_modelsPath}${fileName}.dart'); // Removed .g + // don't overwrite the model file as user could have changed it + // only create the first time + if (!File('$_modelsPath$fileName.dart').existsSync()) { + super + .pageWriter + .write(code, '$_modelsPath$fileName.dart'); // Removed .g + } } } From 700986d25ab50b9cab61257135b828919569f155 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sun, 30 May 2021 14:57:01 -0700 Subject: [PATCH 164/404] Fixes so that Button received name to differentiate widget that is getting the event --- .../state_management/provider_middleware.dart | 10 +++++----- .../utils/middleware_utils.dart | 20 ++++++++++--------- .../provider_generation_configuration.dart | 11 +--------- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 70d970a1..30e226eb 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -42,21 +42,21 @@ class ProviderMiddleware extends Middleware { var providerWidget = ''' ChangeNotifierProvider( create: (context) => - ${modelName}(), + ${modelName}('${node.name}'), child: LayoutBuilder( builder: (context, constraints) { - var widget = ${MiddlewareUtils.generateVariableBody(node)}; + var layout = ${MiddlewareUtils.generateVariableBody(node)}; context .read<${modelName}>() - .setCurrentWidget( - widget); // Setting active state + .setCurrentLayout( + layout); // Setting active state return GestureDetector( onTap: () => context.read< ${modelName}>().OnGesture(), child: Consumer<$modelName>( - builder: (context, ${modelName.toLowerCase()}, child) => ${modelName.toLowerCase()}.currentWidget + builder: (context, ${modelName.toLowerCase()}, child) => ${modelName.toLowerCase()}.currentLayout ), ); }, diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index a6ad2f69..31f88ca2 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -77,16 +77,18 @@ class MiddlewareUtils { ${manager.generateImports()} class ${defaultStateName} extends ChangeNotifier { - Widget currentWidget; - ${defaultStateName}(){} - - // default provider event handler for gestures. - void OnGesture() { - } + LayoutBuilder currentLayout; + final String widgetName; + ${defaultStateName}(this.widgetName); + + // default provider event handler for gestures. + void OnGesture() { + } + + void setCurrentLayout(LayoutBuilder layout) { + currentLayout = layout; + } - void setCurrentWidget(Widget currentWidget) { - this.currentWidget = currentWidget; - } } '''; } diff --git a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart index 07425aac..702d59b6 100644 --- a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart @@ -58,17 +58,8 @@ class ProviderGenerationConfiguration extends GenerationConfiguration { } String _generateMainFunction() { - var providers = registeredModels - .map((e) => 'ChangeNotifierProvider(create: (_) => $e())'); return ''' - runApp( - MultiProvider( - providers: [ - ${providers.join(', ')} - ], - child: MyApp(), - ), - ); + runApp(MyApp()); '''; } } From 6b62c2f78a6688dac02438126b013334f4d89e82 Mon Sep 17 00:00:00 2001 From: Genius Ventures Date: Sun, 30 May 2021 18:24:56 -0700 Subject: [PATCH 165/404] Reverting default state-management to "none" --- lib/configurations/configurations.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index 4eab6a44..26ca0fa6 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -5,5 +5,5 @@ "widgetSpacing": "Expanded", "layoutPrecedence": ["column", "row", "stack"] }, - "state-management": "provider" + "state-management": "none" } From 99dc1d8e884ce9edbf970998786739701827871a Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Sun, 30 May 2021 23:07:19 -0600 Subject: [PATCH 166/404] WIP refactored the how Middlewares were being handled, they are now acting as handlers and have more control over the modification of a node. Furthermore, the middlware's actions were replaced by FileStructureCommands, this allows the importHellper to track the imports. Finally, enabled the FileStructureStrategy to perform a dry run without the creation of new files. --- .../flutter_project_builder.dart | 2 - .../generators/middleware/middleware.dart | 19 ++- .../state_management/bloc_middleware.dart | 69 +++++---- .../state_management/provider_middleware.dart | 63 +++++--- .../state_management/riverpod_middleware.dart | 20 ++- .../state_management/stateful_middleware.dart | 36 +++-- .../utils/middleware_utils.dart | 2 +- .../generators/util/topo_tree_iterator.dart | 4 +- .../commands/entry_file_command.dart | 4 +- .../commands/write_symbol_command.dart | 31 ++-- .../file_structure_strategy_collector.dart | 51 ------- .../pb_file_structure_strategy.dart | 36 +++-- .../provider_file_structure_strategy.dart | 4 - .../riverpod_file_structure_strategy.dart | 9 +- .../bloc_generation_configuration.dart | 2 +- .../pb_generation_configuration.dart | 144 +++++++++--------- .../provider_generation_configuration.dart | 44 ++---- .../riverpod_generation_configuration.dart | 5 +- .../stateful_generation_configuration.dart | 2 +- .../helpers/pb_intermediate_node_tree.dart | 2 +- 20 files changed, 275 insertions(+), 274 deletions(-) delete mode 100644 lib/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index ffd8c202..3d3e169d 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -22,8 +22,6 @@ class FlutterProjectBuilder { var log = Logger('Project Builder'); - final String SYMBOL_DIR_NAME = 'symbols'; - ///The [GenerationConfiguration] that is going to be use in the generation of the code /// ///This is going to be defaulted to [GenerationConfiguration] if nothing else is specified. diff --git a/lib/generation/generators/middleware/middleware.dart b/lib/generation/generators/middleware/middleware.dart index 486f9400..48770f94 100644 --- a/lib/generation/generators/middleware/middleware.dart +++ b/lib/generation/generators/middleware/middleware.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:recase/recase.dart'; @@ -6,9 +7,14 @@ import 'package:recase/recase.dart'; abstract class Middleware { static var variableNames = {}; + /// Using chain of reponsibility to handle the incoming nodes in the generation phase, [nextMiddleware] + /// will be responsible of handling the incoming node or passing it to the next node. + Middleware nextMiddleware; + PBGenerationManager generationManager; + GenerationConfiguration configuration; - Middleware(this.generationManager); + Middleware(this.generationManager, this.configuration, {this.nextMiddleware}); String getNameOfNode(PBIntermediateNode node) => getName(node.name); @@ -20,8 +26,15 @@ abstract class Middleware { : name.replaceRange(index, name.length, '').pascalCase; } + /// Applying the [Middleware] logic to the [node]; modifying it or even eliminating it by returning `null`. Future applyMiddleware(PBIntermediateNode node) => - Future.value(node); + handleNode(node); + + Future handleNode(PBIntermediateNode node) { + return nextMiddleware == null + ? Future.value(node) + : nextMiddleware.applyMiddleware(node); + } void addImportToCache(String id, String path) { PBGenCache().setPathToCache(id, path); @@ -36,3 +49,5 @@ abstract class Middleware { } } } + +class GeneartionConfiguration {} diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 5acbc4c1..6fd972cc 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -1,6 +1,9 @@ import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; @@ -9,13 +12,15 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.d import 'package:recase/recase.dart'; import '../../pb_generation_manager.dart'; import '../middleware.dart'; +import 'package:path/path.dart' as p; class BLoCMiddleware extends Middleware { final PACKAGE_NAME = 'flutter_bloc'; final PACKAGE_VERSION = '^6.1.1'; - BLoCMiddleware(PBGenerationManager generationManager) - : super(generationManager); + BLoCMiddleware(PBGenerationManager generationManager, + GenerationConfiguration configuration) + : super(generationManager, configuration); @override Future applyMiddleware(PBIntermediateNode node) async { @@ -46,7 +51,7 @@ class BLoCMiddleware extends Middleware { ) '''); } - return node; + return handleNode(node); } var parentState = getNameOfNode(node); var generalName = parentState.snakeCase; @@ -71,31 +76,37 @@ class BLoCMiddleware extends Middleware { }); /// Creates state page - await fileStrategy.generatePage( - stateBuffer.toString(), - '$parentDirectory/${generalName}_state', - args: 'VIEW', - ); + fileStrategy.commandCreated(WriteSymbolCommand( + + /// modified the [UUID] to prevent adding import because the state is + /// using `part of` syntax already when importing the bloc + 'STATE${node.currentContext.tree.UUID}', + '${generalName}_state', + stateBuffer.toString(), + relativePath: parentDirectory)); /// Creates event page - await fileStrategy.generatePage( - _createEventPage(parentState), - '$parentDirectory/${generalName}_event', - args: 'VIEW', - ); + fileStrategy.commandCreated(WriteSymbolCommand( + + /// modified the [UUID] to prevent adding import because the event is + /// using `part of` syntax already when importing the bloc + 'EVENT${node.currentContext.tree.UUID}', + '${generalName}_event', + _createEventPage(parentState), + relativePath: parentDirectory)); /// Creates bloc page managerData.addImport(FlutterImport('meta.dart', 'meta')); - await fileStrategy.generatePage( - _createBlocPage( - parentState, - node.name, - ), - '$parentDirectory/${generalName}_bloc', - args: 'VIEW', - ); - - return node; + fileStrategy.commandCreated(WriteSymbolCommand( + node.currentContext.tree.UUID, + '${generalName}_bloc', + _createBlocPage( + parentState, + node.name, + ), + relativePath: parentDirectory)); + + return handleNode(null); } String _createBlocPage(String name, String initialStateName) { @@ -130,13 +141,17 @@ class BLoCMiddleware extends Middleware { '''; } - String getImportPath(PBSharedInstanceIntermediateNode node, fileStrategy) { + String getImportPath(PBSharedInstanceIntermediateNode node, + FileStructureStrategy fileStrategy) { var generalStateName = node.functionCallName .substring(0, node.functionCallName.lastIndexOf('/')); var symbolMaster = PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); - return fileStrategy.GENERATED_PROJECT_PATH + - fileStrategy.RELATIVE_VIEW_PATH + - '${generalStateName.snakeCase}_bloc/${getName(symbolMaster.name).snakeCase}_bloc.dart'; + return p.join( + fileStrategy.GENERATED_PROJECT_PATH, + FileStructureStrategy.RELATIVE_VIEW_PATH, + '${generalStateName.snakeCase}_bloc', + '${getName(symbolMaster.name).snakeCase}_bloc', + ); } } diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 7ca33f55..eb9b59c3 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -5,8 +5,11 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; @@ -22,15 +25,16 @@ class ProviderMiddleware extends Middleware { final PACKAGE_NAME = 'provider'; final PACKAGE_VERSION = '^4.3.2+3'; - ProviderMiddleware(PBGenerationManager generationManager) - : super(generationManager); + ProviderMiddleware(PBGenerationManager generationManager, + ProviderGenerationConfiguration configuration) + : super(generationManager, configuration); @override Future applyMiddleware(PBIntermediateNode node) async { String watcherName; var managerData = node.managerData; - var fileStrategy = node.currentContext.project.fileStructureStrategy - as ProviderFileStructureStrategy; + var fileStrategy = + configuration.fileStructureStrategy as ProviderFileStructureStrategy; if (node is PBSharedInstanceIntermediateNode) { node.currentContext.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); @@ -79,7 +83,8 @@ class ProviderMiddleware extends Middleware { '''; node.generator = StringGeneratorAdapter(providerWidget); } - return node; + + return handleNode(node); } watcherName = getNameOfNode(node); @@ -92,25 +97,36 @@ class ProviderMiddleware extends Middleware { // Write model class for current node var code = MiddlewareUtils.generateModelChangeNotifier( watcherName, modelGenerator, node); - fileStrategy.writeProviderModelFile(code, parentDirectory); - // Generate default node's view page - await fileStrategy.generatePage( - generationManager.generate(node), - p.join(parentDirectory, node.name.snakeCase), - args: 'VIEW', - ); + [ + /// This generated the `changeNotifier` that goes under the [fileStrategy.RELATIVE_MODEL_PATH] + WriteSymbolCommand( + node.currentContext.tree.UUID, + parentDirectory, + code, + symbolPath: fileStrategy.RELATIVE_MODEL_PATH, + ), + // Generate default node's view page + WriteSymbolCommand(node.currentContext.tree.UUID, node.name.snakeCase, + generationManager.generate(node), + relativePath: parentDirectory), + ].forEach(fileStrategy.commandCreated); + + (configuration as ProviderGenerationConfiguration) + .registeredModels + .add(watcherName); // Generate node's states' view pages - node.auxiliaryData?.stateGraph?.states?.forEach((state) async { - await fileStrategy.generatePage( + node.auxiliaryData?.stateGraph?.states?.forEach((state) { + fileStrategy.commandCreated(WriteSymbolCommand( + state.variation.node.currentContext.tree.UUID, + state.variation.node.name.snakeCase, generationManager.generate(state.variation.node), - p.join(parentDirectory, state.variation.node.name.snakeCase), - args: 'VIEW', - ); + relativePath: parentDirectory, + )); }); - return node; + return handleNode(null); } String getImportPath(PBSharedInstanceIntermediateNode node, @@ -118,9 +134,14 @@ class ProviderMiddleware extends Middleware { {bool generateModelPath = true}) { var symbolMaster = PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); + var import = generateModelPath - ? '${fileStrategy.RELATIVE_MODEL_PATH}${getName(symbolMaster.name).snakeCase}.dart' - : '${FileStructureStrategy.RELATIVE_VIEW_PATH}${getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; - return fileStrategy.GENERATED_PROJECT_PATH + import; + ? p.join(fileStrategy.RELATIVE_MODEL_PATH, + getName(symbolMaster.name).snakeCase) + : p.join( + FileStructureStrategy.RELATIVE_VIEW_PATH, + getName(symbolMaster.name).snakeCase, + node.functionCallName.snakeCase); + return p.join(fileStrategy.GENERATED_PROJECT_PATH, import); } } diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 3ee9afab..767a807b 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -1,6 +1,9 @@ import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; @@ -15,15 +18,16 @@ class RiverpodMiddleware extends Middleware { final PACKAGE_NAME = 'flutter_riverpod'; final PACKAGE_VERSION = '^0.12.1'; - RiverpodMiddleware(PBGenerationManager generationManager) - : super(generationManager); + RiverpodMiddleware(PBGenerationManager generationManager, + RiverpodGenerationConfiguration configuration) + : super(generationManager, configuration); @override Future applyMiddleware(PBIntermediateNode node) async { String watcherName; var managerData = node.managerData; - var fileStrategy = node.currentContext.project.fileStructureStrategy - as RiverpodFileStructureStrategy; + var fileStrategy = + configuration.fileStructureStrategy as RiverpodFileStructureStrategy; if (node is PBSharedInstanceIntermediateNode) { node.currentContext.project.genProjectData @@ -47,7 +51,7 @@ class RiverpodMiddleware extends Middleware { node.generator = StringGeneratorAdapter( getConsumer(watcherName, node.functionCallName.camelCase)); } - return node; + return handleNode(node); } watcherName = getNameOfNode(node); @@ -56,9 +60,11 @@ class RiverpodMiddleware extends Middleware { generationManager, node, ); - fileStrategy.writeRiverpodModelFile(code, getName(node.name).snakeCase); + fileStrategy.commandCreated(WriteSymbolCommand( + node.currentContext.tree.UUID, getName(node.name).snakeCase, code, + symbolPath: fileStrategy.RELATIVE_MODEL_PATH)); - return node; + return handleNode(node); } String getConsumer(String name, String pointTo) { diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 2b057b1e..2f648098 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -1,7 +1,8 @@ import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; @@ -9,35 +10,32 @@ import 'package:recase/recase.dart'; import 'package:path/path.dart' as p; class StatefulMiddleware extends Middleware { - StatefulMiddleware(PBGenerationManager generationManager) - : super(generationManager); + StatefulMiddleware(PBGenerationManager generationManager, + GenerationConfiguration configuration) + : super(generationManager, configuration); @override Future applyMiddleware(PBIntermediateNode node) async { - var fileStrategy = node.currentContext.project.fileStructureStrategy - as FlutterFileStructureStrategy; + var fileStrategy = configuration.fileStructureStrategy; if (node is PBSharedInstanceIntermediateNode) { addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - return node; + return handleNode(node); } - var states = [node]; var parentDirectory = getName(node.name).snakeCase; - node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - states.add(state.variation.node); - }); + fileStrategy.commandCreated(WriteSymbolCommand( + node.UUID, parentDirectory, generationManager.generate(node))); - states.forEach((element) async { - element.currentContext.tree.data = node.managerData; - await fileStrategy.generatePage( - generationManager.generate(element), - '$parentDirectory/${element.name.snakeCase}', - args: 'VIEW', - ); + node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + state.variation.node.currentContext.tree.data = node.managerData; + fileStrategy.commandCreated(WriteSymbolCommand( + state.variation.node.currentContext.tree.UUID, + state.variation.node.name.snakeCase, + generationManager.generate(state.variation.node))); }); - return node; + return handleNode(node); } String getImportPath(PBSharedInstanceIntermediateNode node, @@ -49,6 +47,6 @@ class StatefulMiddleware extends Middleware { FileStructureStrategy.RELATIVE_VIEW_PATH, getName(symbolMaster.name).snakeCase, node.functionCallName.snakeCase); - return p.setExtension(path, '.dart'); + return path; } } diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 75ddef51..ad2cb52d 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -87,7 +87,7 @@ class MiddlewareUtils { static String generateVariable(PBIntermediateNode node, {String type = 'var'}) { - return '$type ${node.name.camelCase} = ' + generateVariableBody(node); + return '$type ${node.name.camelCase} = ${generateVariableBody(node)}'; } static String generateEmptyVariable(PBIntermediateNode node, diff --git a/lib/generation/generators/util/topo_tree_iterator.dart b/lib/generation/generators/util/topo_tree_iterator.dart index a84ff44c..a4e5e702 100644 --- a/lib/generation/generators/util/topo_tree_iterator.dart +++ b/lib/generation/generators/util/topo_tree_iterator.dart @@ -40,7 +40,7 @@ class IntermediateTopoIterator var inDegree = HashMap(); items.forEach((tree) { inDegree.putIfAbsent(tree, () => 0); - var dependentOnIterator = tree.dependentOn; + var dependentOnIterator = tree.dependentsOn; while (dependentOnIterator.moveNext()) { inDegree.update(dependentOnIterator.current, (value) => value + 1, ifAbsent: () => 1); @@ -65,7 +65,7 @@ class IntermediateTopoIterator var vertex = noInDegrees.first; noInDegrees.remove(vertex); ordered.add(vertex); - var it = vertex.dependentOn; + var it = vertex.dependentsOn; while (it.moveNext()) { inDegrees[it.current] = inDegrees[it.current] - 1; if (inDegrees[it.current] == 0) { diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart index b40cb547..9485f833 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart @@ -62,8 +62,8 @@ class MyApp extends StatelessWidget { @override Future write(FileStructureStrategy strategy) { - strategy.writeDataToFile(code, strategy.GENERATED_PROJECT_PATH, - p.setExtension(p.join('lib', mainFileName), '.dart'), + strategy.writeDataToFile( + code, strategy.GENERATED_PROJECT_PATH, p.join('lib', mainFileName), UUID: UUID); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 54009fab..860e5918 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -4,26 +4,31 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure /// Command that writes a `symbol` to the project. class WriteSymbolCommand extends NodeFileStructureCommand { - String name; - static final String SYMBOL_PATH = 'lib/widgets'; + static const String DEFAULT_SYMBOL_PATH = 'lib/widgets'; + + final String symbolPath; + String fileName; + + /// The [relativePath] within the [symbolPath] + /// + /// For example, you are looking for `lib/widgets/some_element/element.dart`, + /// then the [relativePath] would be `some_element/` and the [fileName] would be `element.dart`. String relativePath; - WriteSymbolCommand(String UUID, this.name, String code, {this.relativePath}) + WriteSymbolCommand(String UUID, this.fileName, String code, + {this.relativePath = '', this.symbolPath = DEFAULT_SYMBOL_PATH}) : super(UUID, code); - /// Writes a symbol file containing [data] with [name] as its filename. + /// Writes a symbol file containing [data] with [fileName] as its filename. /// /// Returns path to the file that was created. @override Future write(FileStructureStrategy strategy) { - var absPath; - if (relativePath.isEmpty) { - absPath = p.join(strategy.GENERATED_PROJECT_PATH, SYMBOL_PATH); - } else { - absPath = - p.join(strategy.GENERATED_PROJECT_PATH, SYMBOL_PATH, relativePath); - } - strategy.writeDataToFile(code, absPath, name, UUID: UUID); - return Future.value(p.join(absPath, name)); + var absPath = relativePath.isEmpty + ? p.join(strategy.GENERATED_PROJECT_PATH, symbolPath) + : p.join(strategy.GENERATED_PROJECT_PATH, symbolPath, relativePath); + + strategy.writeDataToFile(code, absPath, fileName, UUID: UUID); + return Future.value(p.join(absPath, fileName)); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart b/lib/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart deleted file mode 100644 index 6b9f8d93..00000000 --- a/lib/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; - -/// The [DryRunFileStructureStrategy] is going to mimick a real [FileStructureStrategy], however, its not going to modify the FileSystem. -/// -/// The main use of this class is to analyze the final location of all the [PBIntermediateTree]s given a set of -/// [FileStructureCommand]s that are going to execute. The only use of this class right now if by the [ImportHelper], -/// where we are going to record the final import of all the [PBIntermediateTree]s before actually creating the files. -/// Keep in mind that most of the methods in the [DryRunFileStructureStrategy] are going to do nothing other than -/// notify the [FileWriterObserver]s that new files are being created. -class DryRunFileStructureStrategy extends FileStructureStrategy { - List dryRunCommands; - DryRunFileStructureStrategy(String GENERATED_PROJECT_PATH, - PBPageWriter pageWriter, PBProject pbProject) - : super(GENERATED_PROJECT_PATH, pageWriter, pbProject) { - dryRunCommands = []; - } - - @override - Future setUpDirectories(); - - @override - Future generatePage(String code, String fileName, {args}); - - @override - void writeDataToFile(String data, String directory, String name, - {String UUID}) { - var file = getFile(directory, name); - _notifyObsevers(file.path, UUID); - } - - @override - void appendDataToFile(modFile, String directory, String name, - {String UUID, bool createFileIfNotFound = true}) { - var file = getFile(directory, name); - if (!file.existsSync() && createFileIfNotFound) { - _notifyObsevers(file.path, UUID); - } - } - - @override - void commandCreated(FileStructureCommand command) { - dryRunCommands.add(command); - super.commandCreated(command); - } - - void _notifyObsevers(String path, String UUID) => - fileObservers.forEach((observer) => observer.fileCreated(path, UUID)); -} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index fd77cd62..633ddc8e 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -54,6 +54,17 @@ abstract class FileStructureStrategy implements CommandInvoker { ///Before generating any files, the caller must call the [setUpDirectories] bool isSetUp = false; + /// By the [FileStructureStrategy] being in [dryRunMode], the [FileStructureStrategy] is not + /// going to create anyFiles. + /// + /// Primarly, this mode is to notify the [fileObservers] of a "file creation", without performing + /// the actual creation. A good example of this comes with the [ImportHelper], this oberserver will + /// be documenting the files that are being created as imports to be used later. + bool dryRunMode = false; + + /// Notifies the [fileObserver] of when a file supposed to be created. + bool notifyObserverInDryRun = true; + String _screenDirectoryPath; String _viewDirectoryPath; @@ -104,7 +115,7 @@ abstract class FileStructureStrategy implements CommandInvoker { path = p.join(_screenDirectoryPath, name, poLinker.stripPlatform(tree.rootNode.managerData.platform), name); } - path = p.setExtension(path, '.dart'); + PBGenCache().setPathToCache(uuid, path); } else { logger.warning( @@ -147,14 +158,20 @@ abstract class FileStructureStrategy implements CommandInvoker { /// /// [FileWriterObserver]s are going to be notfied of the new created file. void writeDataToFile(String data, String directory, String name, - {String UUID}) { - var file = getFile(directory, name); - - file.createSync(recursive: true); - file.writeAsStringSync(data); + {String UUID, String ext = '.dart'}) { + var file = getFile(directory, p.setExtension(name, ext)); + + if (!dryRunMode) { + file.createSync(recursive: true); + file.writeAsStringSync(data); + _notifyObservers(file.path, UUID); + } else if (notifyObserverInDryRun) { + _notifyObservers(file.path, UUID); + } + } - fileObservers.forEach((observer) => observer.fileCreated( - file.path, UUID ?? p.basenameWithoutExtension(file.path))); + void _notifyObservers(String path, String UUID) { + fileObservers.forEach((observer) => observer.fileCreated(path, UUID)); } /// Appends [data] into [directory] with the file [name] @@ -165,7 +182,8 @@ abstract class FileStructureStrategy implements CommandInvoker { /// appends the information only if that information does not exist in the file. If no /// [ModFile] function is found, its going to append the information at the end of the lines void appendDataToFile(ModFile modFile, String directory, String name, - {String UUID, bool createFileIfNotFound = true}) { + {String UUID, bool createFileIfNotFound = true, String ext = '.dart'}) { + name = p.setExtension(name, ext); var file = getFile(directory, name); if (file.existsSync()) { var fileLines = file.readAsLinesSync(); diff --git a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart index a0c51842..06e1c224 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart @@ -31,8 +31,4 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { Directory(_providersPath).createSync(recursive: true); Directory(_modelsPath).createSync(recursive: true); } - - void writeProviderModelFile(String code, String fileName) { - super.pageWriter.write(code, '$_modelsPath$fileName.dart'); // Removed .g - } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart index 855eb39b..a08f2013 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; @@ -13,8 +14,8 @@ class RiverpodFileStructureStrategy extends FileStructureStrategy { RiverpodFileStructureStrategy( String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) : super(genProjectPath, pageWriter, pbProject) { - _providersPath = '$genProjectPath$RELATIVE_PROVIDER_PATH'; - _modelsPath = '$genProjectPath$RELATIVE_MODEL_PATH'; + _providersPath = p.join(genProjectPath, RELATIVE_PROVIDER_PATH); + _modelsPath = p.join(genProjectPath, RELATIVE_MODEL_PATH); } @override @@ -32,8 +33,6 @@ class RiverpodFileStructureStrategy extends FileStructureStrategy { } void writeRiverpodModelFile(String code, String fileName) { - super - .pageWriter - .write(code, '$_modelsPath$fileName.dart'); // Removed .g + super.pageWriter.write(code, '$_modelsPath$fileName.dart'); // Removed .g } } diff --git a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart index 91d823dd..908963b5 100644 --- a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart @@ -13,7 +13,7 @@ class BLoCGenerationConfiguration extends GenerationConfiguration { 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject); - registerMiddleware(BLoCMiddleware(generationManager)); + registerMiddleware(BLoCMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); return super.setUpConfiguration(pbProject); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 51821065..83f2e87f 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,3 +1,5 @@ +import 'dart:collection'; + import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; @@ -10,7 +12,6 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_structure_strategy_collector.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; @@ -22,7 +23,6 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; @@ -30,15 +30,14 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orient import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; import 'package:path/path.dart' as p; -import 'package:uuid/uuid.dart'; abstract class GenerationConfiguration with PBPlatformOrientationGeneration { FileStructureStrategy fileStructureStrategy; Logger logger; - final Set _middleware = {}; - Set get middlewares => _middleware; + /// The [_head] of a [Middlware] link list. + Middleware _head; ///The manager in charge of the independent [PBGenerator]s by providing an interface for adding imports, global variables, etc. /// @@ -70,37 +69,37 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ///This is going to modify the [PBIntermediateNode] in order to affect the structural patterns or file structure produced. Future applyMiddleware(PBIntermediateNode node) async { - var it = _middleware.iterator; - while (it.moveNext()) { - node = await it.current.applyMiddleware(node); + if (containsState(node) || containsMasterState(node)) { + node = await _head.applyMiddleware(node); } return node; } - bool _isMasterState(PBSharedInstanceIntermediateNode node) { - if (node.isMasterState) { - return true; + bool containsMasterState(PBIntermediateNode node) { + if (node is PBSharedInstanceIntermediateNode) { + if (node.isMasterState) { + return true; + } + return containsState( + PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID)); } - var symbolMaster = - PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); - return symbolMaster?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false; + return false; } + bool containsState(PBIntermediateNode node) => + node?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false; + ///Applying the registered [Middleware] to all the [PBIntermediateNode]s within the [PBIntermediateTree] Future _applyMiddleware(PBIntermediateTree tree) async { - for (var node in tree) { - if ((node is PBSharedInstanceIntermediateNode && _isMasterState(node)) || - (node?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false)) { - await applyMiddleware(node); - } - } - return tree; + tree.rootNode = + (await Future.wait(tree.map(applyMiddleware).toList())).first; + + return tree.rootNode == null ? null : tree; } Future generateTrees( List trees, PBProject project) async { for (var tree in trees) { - // var tree = trees.current; tree.rootNode.currentContext.generationManager = generationManager; tree.data.addImport(FlutterImport('material.dart', 'flutter')); @@ -108,8 +107,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var fileName = tree.identifier?.snakeCase ?? 'no_name_found'; // Relative path to the file to create - var relPath = - p.setExtension(p.join(tree.name.snakeCase, fileName), '.dart'); + var relPath = p.join(tree.name.snakeCase, fileName); // Change relative path if current tree is part of multi-platform setup if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { @@ -121,7 +119,10 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { (tree.rootNode as InheritedScaffold).isHomeScreen) { await _setMainScreen(tree, relPath, project.projectName); } - await _applyMiddleware(tree); + tree = await _applyMiddleware(tree); + if (tree == null) { + continue; + } fileStructureStrategy .commandCreated(_createCommand(fileName, tree, project)); @@ -132,14 +133,18 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { Future generateProject(PBProject pb_project) async { ///First we are going to perform a dry run in the generation to ///gather all the necessary information - configDryRun(pb_project); + await setUpConfiguration(pb_project); + + fileStructureStrategy.dryRunMode = true; + fileStructureStrategy.addFileObserver(_importProcessor); pb_project.fileStructureStrategy = fileStructureStrategy; + + pb_project.lockData = true; await generateTrees(pb_project.forest, pb_project); + pb_project.lockData = false; ///After the dry run is complete, then we are able to create the actual files. - await setUpConfiguration(pb_project); - pb_project.fileStructureStrategy = fileStructureStrategy; - // dryRunCommands.forEach(fileStructureStrategy.commandCreated); + fileStructureStrategy.dryRunMode = false; await generateTrees(pb_project.forest, pb_project); await _commitDependencies(pb_project.projectAbsPath); @@ -153,40 +158,37 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { if (_importProcessor.imports.isNotEmpty) { var treePath = p.join(project.projectAbsPath, ExportPlatformCommand.WIDGET_PATH, fileName); - _traverseTreeForImports( - tree, p.setExtension(treePath, '.dart'), project.projectName); + _addDependencyImports(tree, treePath, project.projectName); } command = ExportPlatformCommand( tree.UUID, tree.rootNode.currentContext.tree.data.platform, fileName, - p.setExtension(tree.rootNode.name.snakeCase, '.dart'), + tree.rootNode.name.snakeCase, generationManager.generate(tree.rootNode), ); } else if (tree.rootNode is InheritedScaffold) { if (_importProcessor.imports.isNotEmpty) { var treePath = p.join( project.projectAbsPath, WriteScreenCommand.SCREEN_PATH, fileName); - _traverseTreeForImports( - tree, p.setExtension(treePath, '.dart'), project.projectName); + _addDependencyImports(tree, treePath, project.projectName); } command = WriteScreenCommand( tree.UUID, - p.setExtension(fileName, '.dart'), + fileName, tree.name.snakeCase, generationManager.generate(tree.rootNode), ); } else { - var relativePath = '${tree.name.snakeCase}/'; + var relativePath = tree.name.snakeCase; //symbols if (_importProcessor.imports.isNotEmpty) { var treePath = p.join(project.projectAbsPath, - WriteSymbolCommand.SYMBOL_PATH, relativePath, fileName); - _traverseTreeForImports( - tree, p.setExtension(treePath, '.dart'), project.projectName); + WriteSymbolCommand.DEFAULT_SYMBOL_PATH, relativePath, fileName); + _addDependencyImports(tree, treePath, project.projectName); } command = WriteSymbolCommand( tree.UUID, - p.setExtension(fileName, '.dart'), + fileName, generationManager.generate(tree.rootNode), relativePath: relativePath, ); @@ -200,43 +202,30 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { /// If an import path is found, it will be added to the `tree`'s data. The package format /// for imports is going to be enforced, therefore, [packageName] is going to be /// a required parameter. - void _traverseTreeForImports( + void _addDependencyImports( PBIntermediateTree tree, String treeAbsPath, String packageName) { - var iter = tree.dependentOn; + var iter = tree.dependentsOn; var addImport = tree.rootNode.managerData.addImport; while (iter.moveNext()) { - var dependency = iter.current; - var import = _importProcessor.getImport(dependency.UUID); - if (import != null) { - addImport(FlutterImport(import, packageName)); - } + _importProcessor.getFormattedImports( + iter.current.UUID, + importMapper: (import) => addImport(FlutterImport(import, packageName)), + ); } } void registerMiddleware(Middleware middleware) { if (middleware != null) { - middleware.generationManager = generationManager; - _middleware.add(middleware); - } - } + if (_head == null) { + _head = middleware; + } else { + middleware.nextMiddleware = _head; + _head = middleware; - /// going to run the [generateProject] without actually creating or modifying any file - /// - /// The main purpose of this is to collect all the information necessary to run a successful - /// generation. For example, if we ran it normally, there would be imports missing because we could - /// not determine the final position of some dependencies. - FileStructureStrategy configDryRun(PBProject pbProject) { - fileStructureStrategy = DryRunFileStructureStrategy( - pbProject.projectAbsPath, pageWriter, pbProject); - fileStructureStrategy.addFileObserver(_importProcessor); - - ///TODO: Once [GenerationConfiguraion] is init from the beginning in PBC, we can remove the need of a queue - pbProject.genProjectData.commandQueue - .forEach(fileStructureStrategy.commandCreated); - - logger.info('Running Generation Dry Run...'); - return fileStructureStrategy; + middleware.generationManager = generationManager; + } + } } ///Configure the required classes for the [PBGenerationConfiguration] @@ -244,7 +233,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject); commandObservers.add(fileStructureStrategy); - fileStructureStrategy.addFileObserver(_importProcessor); // Execute command queue var queue = pbProject.genProjectData.commandQueue; @@ -266,11 +254,12 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { Future _setMainScreen( PBIntermediateTree tree, String outputMain, String packageName) async { var nodeInfo = _determineNode(tree, outputMain); - fileStructureStrategy.commandCreated(EntryFileCommand('main_file', + fileStructureStrategy.commandCreated(EntryFileCommand( entryScreenName: nodeInfo[0], - entryScreenImport: - FlutterImport(_importProcessor.getImport(tree.UUID), packageName) - .toString())); + entryScreenImport: _importProcessor + .getFormattedImports(tree.UUID, + importMapper: (import) => FlutterImport(import, packageName)) + .join('\n'))); } List _determineNode(PBIntermediateTree tree, String outputMain) { @@ -297,12 +286,12 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var rawImports = getPlatformImports(screenName); rawImports.add(p.join( - mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH, + fileStructureStrategy.GENERATED_PROJECT_PATH, OrientationBuilderCommand.DIR_TO_ORIENTATION_BUILDER, OrientationBuilderCommand.NAME_TO_ORIENTAION_BUILDER, )); rawImports.add(p.join( - mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH, + fileStructureStrategy.GENERATED_PROJECT_PATH, ResponsiveLayoutBuilderCommand.DIR_TO_RESPONSIVE_LAYOUT, ResponsiveLayoutBuilderCommand.NAME_TO_RESPONSIVE_LAYOUT, )); @@ -323,7 +312,12 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var imports = {}; platformOrientationMap.forEach((key, map) { map.forEach((key, tree) { - imports.add(_importProcessor.getImport(tree.UUID)); + imports.add(_importProcessor + .getFormattedImports( + tree.UUID, + importMapper: (import) => FlutterImport(import), + ) + .join('\n')); }); }); // TODO: add import to responsive layout builder diff --git a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart index 4669aaef..2bd55f1c 100644 --- a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart @@ -1,11 +1,8 @@ -import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/provider_middleware.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; @@ -23,7 +20,7 @@ class ProviderGenerationConfiguration extends GenerationConfiguration { 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); fileStructureStrategy = ProviderFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject); - registerMiddleware(ProviderMiddleware(generationManager)); + registerMiddleware(ProviderMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); } @@ -31,32 +28,21 @@ class ProviderGenerationConfiguration extends GenerationConfiguration { @override Future generateProject(PBProject pb_project) async { await super.generateProject(pb_project); - if (pageWriter is PBFlutterWriter) { - Set imports = {FlutterImport('provider.dart', 'provider')}; - imports.addAll(registeredModels - .map((e) => FlutterImport('models/${e.snakeCase}.dart')) - .toList()); + Set imports = {FlutterImport('provider.dart', 'provider')}; + imports.addAll(registeredModels + .map((e) => FlutterImport( + p.setExtension( + p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'models', + e.snakeCase), + '.dart'), + pb_project.projectName)) + .toList()); - (pageWriter as PBFlutterWriter).rewriteMainFunction( - p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'lib/main.dart'), - _generateMainFunction(), - imports: imports, - ); - } - } - - ///This is going to modify the [PBIntermediateNode] in order to affect the structural patterns or file structure produced. - @override - Future applyMiddleware(PBIntermediateNode node) async { - var it = middlewares.iterator; - while (it.moveNext()) { - node = await it.current.applyMiddleware(node); - if (it.current is ProviderMiddleware && - node is PBSharedInstanceIntermediateNode) { - registeredModels.add(it.current.getName(node.functionCallName)); - } - } - return node; + (pageWriter as PBFlutterWriter).rewriteMainFunction( + p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'lib/main.dart'), + _generateMainFunction(), + imports: imports, + ); } String _generateMainFunction() { diff --git a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart index 1eb2c243..7f039b87 100644 --- a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/generation/generators/value_objects/generation_con import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:quick_log/quick_log.dart'; +import 'package:path/path.dart' as p; class RiverpodGenerationConfiguration extends GenerationConfiguration { RiverpodGenerationConfiguration(); @@ -16,7 +17,7 @@ class RiverpodGenerationConfiguration extends GenerationConfiguration { 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); fileStructureStrategy = RiverpodFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject); - registerMiddleware(RiverpodMiddleware(generationManager)); + registerMiddleware(RiverpodMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); } @@ -26,7 +27,7 @@ class RiverpodGenerationConfiguration extends GenerationConfiguration { await super.generateProject(pb_project); if (pageWriter is PBFlutterWriter) { (pageWriter as PBFlutterWriter).rewriteMainFunction( - fileStructureStrategy.GENERATED_PROJECT_PATH + 'lib/main.dart', + p.join(fileStructureStrategy.GENERATED_PROJECT_PATH, 'lib/main.dart'), _generateMainFunction(), imports: {FlutterImport('flutter_riverpod.dart', 'flutter_riverpod')}, ); diff --git a/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart index 3dfbaffa..7afa7978 100644 --- a/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart @@ -9,7 +9,7 @@ class StatefulGenerationConfiguration extends GenerationConfiguration { Future setUpConfiguration(pbProject) async { fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject); - registerMiddleware(StatefulMiddleware(generationManager)); + registerMiddleware(StatefulMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); return super.setUpConfiguration(pbProject); diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 43f6ca35..fb8d6c75 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -43,7 +43,7 @@ class PBIntermediateTree extends Iterable { /// /// The [dependent] or its [dependent.rootNode] can not be `null` void addDependent(PBIntermediateTree dependent) { - if (dependent != null && dependent.rootNode != null) { + if (dependent != null) { _dependentsOn.add(dependent); } } From ef9f89fa2722a21f81b9e635d90869c63b9ece05 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Sun, 30 May 2021 23:09:10 -0600 Subject: [PATCH 167/404] WIP enabled the PBIntermediateTree and PBProject to lock their data, in other words, in certain phases their data will reject any request to modification. This was necessary due to the inability to perform deep clone on certain objects to prevent modification in dryrun phases. --- .../import_helper.dart | 42 ++++++++++++++----- .../commands/entry_file_command.dart | 4 +- .../helpers/pb_intermediate_node_tree.dart | 34 +++++++++++---- .../helpers/pb_project.dart | 34 ++++++++++++++- 4 files changed, 92 insertions(+), 22 deletions(-) diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 3fd08983..67b85814 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -7,9 +7,11 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/generation/flutter_project_builder/file_writer_observer.dart'; +import 'package:path/path.dart' as p; class ImportHelper implements FileWriterObserver { - final Map imports = {}; + final Map> imports = {}; + final List _importBaseNames = []; /// Traverse the [node] tree, check if any nodes need importing, /// and add the relative import from [path] to the [node] @@ -60,23 +62,43 @@ class ImportHelper implements FileWriterObserver { return currentImports; } - String getImport(String UUID) { + List getImport(String UUID) { if (imports.containsKey(UUID)) { - return imports[UUID]; + return imports[UUID].toList(); } return null; } + List getFormattedImports(String UUID, + {dynamic Function(String import) importMapper}) { + importMapper ??= (String path) => path; + return getImport(UUID)?.map(importMapper)?.toList() ?? []; + } + + /// Looks that we are not tracking the file in the imports by comparing the + /// [import]s basename with the collection of [_importBaseNames]. + bool containsBaseName(String import) { + return _importBaseNames.contains(p.basename(import)); + } + + /// Adding [import] to the [imports], allowing other callers to lookup their dependencies using + /// their [UUID]. + /// + /// Multiple [import]s could be added under the same [UUID]. This is to allow the + /// callers of [addImport] to add additional imports for other packages or files that are + /// certain to be required. The only contrain is that the [import] basename need to be + /// unique across all [imports], if its not, its not going to be added to the [imports]. For example, + /// when we [addImport] `/example.dart`, then `/example.dart`, only + /// the `/example.dart` is going to be recorded in [imports]. void addImport(String import, String UUID) { - if (import != null && UUID != null) { - imports[UUID] = import; + if (import != null && UUID != null && !containsBaseName(import)) { + imports[UUID] ??= {}; + imports[UUID].add(import); + _importBaseNames.add(p.basename(import)); } } @override - void fileCreated(String filePath, String fileUUID) { - if (filePath != null && fileUUID != null) { - imports[fileUUID] = filePath; - } - } + void fileCreated(String filePath, String fileUUID) => + addImport(filePath, fileUUID); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart index 9485f833..4cded48a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart @@ -24,13 +24,13 @@ class EntryFileCommand extends NodeFileStructureCommand { /// The code of the main() method inside [mainFileName] final String mainCode; - EntryFileCommand(String UUID, + EntryFileCommand( {this.mainFileName = 'main', this.entryScreenName, this.entryScreenImport, this.projectName = 'Parabeac-Core Generated Project', this.mainCode = 'runApp(MyApp());'}) - : super(UUID, ''' + : super('ENTRY_FILE', ''' import 'package:flutter/material.dart'; $entryScreenImport diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index fb8d6c75..9d7ad8cf 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -14,26 +14,42 @@ class PBIntermediateTree extends Iterable { String get UUID => _UUID; TREE_TYPE tree_type = TREE_TYPE.SCREEN; - PBGenerationViewData data; - PBIntermediateNode _rootNode; - set rootNode(PBIntermediateNode rootNode) { - _rootNode = rootNode; - identifier = rootNode?.name ?? name; + + /// This flag makes the data in the [PBIntermediateTree] unmodifiable. Therefore, + /// if a change is made and [lockData] is `true`, the change is going to be ignored. + /// + /// This is a workaround to process where the data needs to be analyzed without any modification done to it. + /// Furthermore, this is a workaround to the unability of creating a copy of the [PBIntermediateTree] to prevent + /// the modifications to the object (https://github.com/dart-lang/sdk/issues/3367). As a result, the [lockData] flag + /// has to be used to prevent those modification in phases where the data needs to be analyzed but unmodified. + bool lockData = false; + + PBGenerationViewData _data; + PBGenerationViewData get data => _data; + set data(PBGenerationViewData viewData) { + if (!lockData) { + _data = viewData; + } } + PBIntermediateNode _rootNode; PBIntermediateNode get rootNode => _rootNode; + set rootNode(PBIntermediateNode rootNode) { + if (!lockData) { + _rootNode = rootNode; + identifier = rootNode?.name ?? name; + } + } /// List of [PBIntermediteTree]s that `this` depends on. /// /// In other words, `this` can not be generated until its [dependentsOn]s are generated. Set _dependentsOn; - Iterator get dependentOn => _dependentsOn.iterator; + Iterator get dependentsOn => _dependentsOn.iterator; String name; String identifier; - List dependentsOn; - PBIntermediateTree(this.name) { _dependentsOn = {}; _UUID = Uuid().v4(); @@ -43,7 +59,7 @@ class PBIntermediateTree extends Iterable { /// /// The [dependent] or its [dependent.rootNode] can not be `null` void addDependent(PBIntermediateTree dependent) { - if (dependent != null) { + if (dependent != null && !lockData) { _dependentsOn.add(dependent); } } diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index 3a9743bf..bf652d01 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -6,8 +6,35 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod class PBProject { final String projectName; final String projectAbsPath; - List forest = []; + + /// This flag makes the data in the [PBProject] unmodifiable. Therefore, + /// if a change is made and [lockData] is `true`, the change is going to be ignored. + /// + /// This affects the [forest], based on the value given to [lockData] will make the [forest] either + /// modifiable or unmodifiable. + /// + /// This is a workaround to process where the data needs to be analyzed without any modification done to it. + /// Furthermore, this is a workaround to the unability of creating a copy of the [PBProject] to prevent + /// the modifications to the object (https://github.com/dart-lang/sdk/issues/3367). As a result, the [lockData] flag + /// has to be used to prevent those modification in phases where the data needs to be analyzed but unmodified. + bool _lockData = false; + bool get lockData => _lockData; + set lockData(lock) { + _lockData = lock; + _forest.forEach((tree) => tree.lockData = lock); + } + + List _forest; + List get forest => _forest; + set forest(List forest) { + if (!lockData) { + _forest = forest; + } + } + List sharedStyles = []; + @Deprecated( + 'Use the fileStructureStrategy within the GenerationConfiguration') FileStructureStrategy _fileStructureStrategy; PBGenerationProjectData _genProjectData; @@ -15,13 +42,18 @@ class PBProject { _genProjectData = projectData; PBGenerationProjectData get genProjectData => _genProjectData; + @Deprecated( + 'Use the fileStructureStrategy within the GenerationConfiguration') set fileStructureStrategy(FileStructureStrategy strategy) => _fileStructureStrategy = strategy; + @Deprecated( + 'Use the fileStructureStrategy within the GenerationConfiguration') FileStructureStrategy get fileStructureStrategy => _fileStructureStrategy; PBProject(this.projectName, this.projectAbsPath, this.sharedStyles, {FileStructureStrategy fileStructureStrategy}) { + _forest = []; _genProjectData = PBGenerationProjectData(); _fileStructureStrategy = fileStructureStrategy; _genProjectData = PBGenerationProjectData(); From 3947000d4d878f60e37fdee308f02926b90ee3ea Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Tue, 1 Jun 2021 16:15:38 -0600 Subject: [PATCH 168/404] Fixed Figma Constraint Interpretation --- lib/input/helper/figma_constraint_to_pbdl.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/input/helper/figma_constraint_to_pbdl.dart b/lib/input/helper/figma_constraint_to_pbdl.dart index c11fdb8d..d494ab16 100644 --- a/lib/input/helper/figma_constraint_to_pbdl.dart +++ b/lib/input/helper/figma_constraint_to_pbdl.dart @@ -25,19 +25,19 @@ PBDLConstraints _convertFigmaConstraint(FigmaConstraintType figmaConstraintType, } else if (figmaConstraintType == FigmaConstraintType.TOP) { constraints.pinTop = true; constraints.pinBottom = false; - constraints.fixedHeight = false; + constraints.fixedHeight = true; } else if (figmaConstraintType == FigmaConstraintType.LEFT) { constraints.pinLeft = true; constraints.pinRight = false; - constraints.fixedWidth = false; + constraints.fixedWidth = true; } else if (figmaConstraintType == FigmaConstraintType.RIGHT) { constraints.pinLeft = false; constraints.pinRight = true; - constraints.fixedWidth = false; + constraints.fixedWidth = true; } else if (figmaConstraintType == FigmaConstraintType.BOTTOM) { constraints.pinTop = false; constraints.pinBottom = true; - constraints.fixedHeight = false; + constraints.fixedHeight = true; } else if (figmaConstraintType == FigmaConstraintType.CENTER) { if (isVertical) { constraints.pinTop = false; From e5a3de9b6ee77a45b09f8f61406b2b51aa41cbb1 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 1 Jun 2021 16:30:07 -0600 Subject: [PATCH 169/404] Fix ProjectBuilderTest by creating iterator from empty list. Previously the issue stemmed from `HasNextIterator` not being a subtype of `Iterator` --- test/lib/output_services/project_builder_test.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index b6e7faf5..545ef8e7 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -1,4 +1,3 @@ -import 'dart:collection'; import 'dart:io'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; @@ -76,7 +75,7 @@ void main() { when(intermediateTree.name).thenReturn('testTree'); when(intermediateTree.data).thenReturn(PBGenerationViewData()); when(intermediateTree.dependentOn) - .thenReturn(HasNextIterator(null) as Iterator); + .thenReturn([].iterator); when(project.projectName).thenReturn( '${Directory.current.path}/test/lib/output_services/temp2/'); From 97a785778c6d9b59f896ae3ada07fe5ebec54f5e Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 1 Jun 2021 16:40:21 -0600 Subject: [PATCH 170/404] Change path of bloc export test in bloc_test.dart --- test/lib/middleware/bloc_test.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/lib/middleware/bloc_test.dart b/test/lib/middleware/bloc_test.dart index 79b9c5ac..3cf1af72 100644 --- a/test/lib/middleware/bloc_test.dart +++ b/test/lib/middleware/bloc_test.dart @@ -102,22 +102,23 @@ void main() { }); test('BLoC Strategy Test', () async { + var relativeViewPath = mockFileStructureStrategy.RELATIVE_VIEW_PATH; await mockFileStructureStrategy.setUpDirectories(); var tempNode = await bLoCMiddleware.applyMiddleware(node); expect(tempNode is PBIntermediateNode, true); expect( await File( - '${testingPath}lib/view/some_element_bloc/some_element_bloc.dart') + '${testingPath}${relativeViewPath}some_element_bloc/some_element_bloc.dart') .exists(), true); expect( await File( - '${testingPath}lib/view/some_element_bloc/some_element_event.dart') + '${testingPath}${relativeViewPath}some_element_bloc/some_element_event.dart') .exists(), true); expect( await File( - '${testingPath}lib/view/some_element_bloc/some_element_state.dart') + '${testingPath}${relativeViewPath}some_element_bloc/some_element_state.dart') .exists(), true); }); From 8cadb956638d9633df21799286aa68e32e5bc3bd Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 1 Jun 2021 16:41:54 -0600 Subject: [PATCH 171/404] Change view path of stateful_test to be dynamic --- test/lib/middleware/stateful_test.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/lib/middleware/stateful_test.dart b/test/lib/middleware/stateful_test.dart index 7e9f047f..130d1a8f 100644 --- a/test/lib/middleware/stateful_test.dart +++ b/test/lib/middleware/stateful_test.dart @@ -102,17 +102,18 @@ void main() { }); test('Stateful Strategy Test', () async { + var relativeViewPath = mockFileStructureStrategy.RELATIVE_VIEW_PATH; await mockFileStructureStrategy.setUpDirectories(); var tempNode = await bLoCMiddleware.applyMiddleware(node); expect(tempNode is PBIntermediateNode, true); expect( await File( - '${testingPath}lib/view/some_element/some_element_blue.dart') + '${testingPath}${relativeViewPath}some_element/some_element_blue.dart') .exists(), true); expect( await File( - '${testingPath}lib/view/some_element/some_element_green.dart') + '${testingPath}${relativeViewPath}some_element/some_element_green.dart') .exists(), true); }); From 7750d2103163ae1e8ba616d292ccab6dbb890d40 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 1 Jun 2021 16:54:09 -0600 Subject: [PATCH 172/404] Add default value to relativePath for WriteSymbolCommand using `anyNamed` method for WriteSymbolCommandTest verification --- .../commands/write_symbol_command.dart | 3 ++- test/lib/generation/commands/write_symbol_command_test.dart | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 0f627a26..f224e865 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -8,7 +8,8 @@ class WriteSymbolCommand extends NodeFileStructureCommand { final String SYMBOL_PATH = 'lib/widgets'; String relativePath; - WriteSymbolCommand(String UUID, this.name, String code, {this.relativePath}) + WriteSymbolCommand(String UUID, this.name, String code, + {this.relativePath = ''}) : super(UUID, code); /// Writes a symbol file containing [data] with [name] as its filename. diff --git a/test/lib/generation/commands/write_symbol_command_test.dart b/test/lib/generation/commands/write_symbol_command_test.dart index c43d7e42..8d7b51d2 100644 --- a/test/lib/generation/commands/write_symbol_command_test.dart +++ b/test/lib/generation/commands/write_symbol_command_test.dart @@ -39,8 +39,9 @@ void main() { test('Makes sure that the command is using the strategy to write a file', () async { await command.write(strategy); - var verification = - verify(strategy.writeDataToFile(captureAny, any, captureAny)); + var verification = verify(strategy.writeDataToFile( + captureAny, any, captureAny, + UUID: anyNamed('UUID'))); /// Make sure we are writting to the file using the strategy expect(verification.captured.first, symData); From 93df78b9b291c3c4029519a282078f50c9a98fa6 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 1 Jun 2021 16:56:48 -0600 Subject: [PATCH 173/404] Add `anyNamed` method for WriteScreenCommandTest verification --- test/lib/generation/commands/write_screen_command_test.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/lib/generation/commands/write_screen_command_test.dart b/test/lib/generation/commands/write_screen_command_test.dart index da3f9755..ce39f4bb 100644 --- a/test/lib/generation/commands/write_screen_command_test.dart +++ b/test/lib/generation/commands/write_screen_command_test.dart @@ -47,8 +47,9 @@ void main() { test('Testing writing a screen', () async { await command.write(strategy); - var verification = - verify(strategy.writeDataToFile(captureAny, any, captureAny)); + var verification = verify(strategy.writeDataToFile( + captureAny, any, captureAny, + UUID: anyNamed('UUID'))); /// Make sure we are writting to the file using the strategy expect(verification.captured.first, screenData); From 579945e1a3b78fa4f8c821b67932b541376b52b7 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 1 Jun 2021 17:10:47 -0600 Subject: [PATCH 174/404] Add await to command.write. Add `anyNamed` method to `when()` mockito call. --- test/lib/generation/import_test.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/lib/generation/import_test.dart b/test/lib/generation/import_test.dart index 0ebfd92a..d7e67c89 100644 --- a/test/lib/generation/import_test.dart +++ b/test/lib/generation/import_test.dart @@ -96,7 +96,8 @@ void main() { _fileStructureStrategy = FileStructureStrategyMock(); importHelper = ImportHelper(); - when(_fileStructureStrategy.writeDataToFile(any, any, any)) + when(_fileStructureStrategy.writeDataToFile(any, any, any, + UUID: anyNamed('UUID'))) .thenAnswer((invocation) { var dir = invocation.positionalArguments[1]; var name = invocation.positionalArguments[2]; @@ -109,10 +110,10 @@ void main() { }); when(_fileStructureStrategy.GENERATED_PROJECT_PATH).thenReturn(genPath); }); - test('Testing import generation when imports are generated', () { + test('Testing import generation when imports are generated', () async { var command = WriteScreenCommand( 'UUID', 'some_dart_page.dart', 'homescreen/', 'dummy code'); - command.write(_fileStructureStrategy); + await command.write(_fileStructureStrategy); expect(importHelper.getImport('UUID'), completePath); }); }); From 984b85c7d4d7c4391d174a4cd00125f25627da4c Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Wed, 2 Jun 2021 13:33:21 -0600 Subject: [PATCH 175/404] Added the breakpoints into the configuration object and enforced the use of the PBConfiguration class by replacing the map in MainInfo() by the class. --- lib/controllers/controller.dart | 36 ++------ lib/controllers/design_controller.dart | 8 +- lib/controllers/figma_controller.dart | 8 +- lib/controllers/interpret.dart | 7 +- lib/controllers/main_info.dart | 11 +-- lib/controllers/sketch_controller.dart | 8 +- .../flutter_project_builder.dart | 33 ++------ .../responsive_layout_builder_command.dart | 2 +- .../helpers/pb_configuration.dart | 61 ++++++++++++-- .../helpers/pb_configuration.g.dart | 5 +- ...b_platform_orientation_linker_service.dart | 14 ++-- lib/main.dart | 84 +++++++++---------- .../services/interpret_test.dart | 2 +- 13 files changed, 133 insertions(+), 146 deletions(-) diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index 80fc30e7..a129048f 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -4,11 +4,11 @@ import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.da import 'package:parabeac_core/input/helper/asset_processing_service.dart'; import 'package:parabeac_core/input/helper/azure_asset_service.dart'; import 'package:parabeac_core/input/helper/design_project.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:quick_log/quick_log.dart'; import 'dart:convert'; import 'dart:io'; import 'main_info.dart'; -import 'package:path/path.dart' as p; abstract class Controller { ///SERVICE @@ -19,8 +19,7 @@ abstract class Controller { void convertFile( var fileAbsPath, var projectPath, - var configurationPath, - var configType, { + PBConfiguration configuration, { bool jsonOnly = false, DesignProject designProject, AssetProcessingService apService, @@ -30,40 +29,19 @@ abstract class Controller { return stopAndToJson(designProject, apService); } - Interpret().init(projectPath); + Interpret().init(projectPath, configuration); var pbProject = await Interpret().interpretAndOptimize( - designProject, p.basenameWithoutExtension(projectPath), projectPath); + designProject, configuration.projectName, configuration.genProjectPath); var fpb = FlutterProjectBuilder( - project: pbProject, pageWriter: PBFlutterWriter()); + MainInfo().configuration.generationConfiguration, + project: pbProject, + pageWriter: PBFlutterWriter()); await fpb.convertToFlutterProject(); } - void configure(var configurationPath, var configType) async { - Map configurations; - try { - if (configurationPath == null || configurationPath.isEmpty) { - configurations = MainInfo().defaultConfigs; - } else { - configurations = - json.decode(File(configurationPath).readAsStringSync()); - } - } catch (e, stackTrace) { - await MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); - log.error(e.toString()); - } - - ///SET CONFIGURATION - // Setting configurations globally - MainInfo().configurations = configurations; - MainInfo().configurationType = configType; - } - /// Method that returns the given path and ensures /// it ends with a / String verifyPath(String path) { diff --git a/lib/controllers/design_controller.dart b/lib/controllers/design_controller.dart index ba0e80e3..8192eeb2 100644 --- a/lib/controllers/design_controller.dart +++ b/lib/controllers/design_controller.dart @@ -15,22 +15,18 @@ class DesignController extends Controller { void convertFile( var pbdf, var outputPath, - var configurationPath, - var configType, { + configuration, { bool jsonOnly = false, DesignProject designProject, AssetProcessingService apService, }) async { - configure(configurationPath, configType); - var designProject = generateDesignProject(pbdf, outputPath); AzureAssetService().projectUUID = pbdf['id']; super.convertFile( pbdf, outputPath, - configurationPath, - configType, + configuration, designProject: designProject, jsonOnly: jsonOnly, ); diff --git a/lib/controllers/figma_controller.dart b/lib/controllers/figma_controller.dart index dfcba396..7cf94d6d 100644 --- a/lib/controllers/figma_controller.dart +++ b/lib/controllers/figma_controller.dart @@ -18,14 +18,11 @@ class FigmaController extends Controller { void convertFile( var jsonFigma, var outputPath, - var configurationPath, - var configType, { + var configuration, { bool jsonOnly = false, DesignProject designProject, AssetProcessingService apService, }) async { - configure(configurationPath, configType); - var figmaProject = generateFigmaTree(jsonFigma, outputPath); figmaProject = declareScaffolds(figmaProject); @@ -35,8 +32,7 @@ class FigmaController extends Controller { super.convertFile( jsonFigma, outputPath, - configurationPath, - configType, + configuration, designProject: figmaProject, jsonOnly: jsonOnly, apService: apService, diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index e81ce95c..99717904 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -39,8 +39,10 @@ class Interpret { PBProject _pb_project; PBSymbolLinkerService _pbSymbolLinkerService; PBPrototypeLinkerService _pbPrototypeLinkerService; + PBConfiguration configuration; - void init(String projectName) { + void init(String projectName, configuration) { + this.configuration ??= configuration; log = Logger(runtimeType.toString()); _interpret._pbSymbolLinkerService = PBSymbolLinkerService(); _interpret._pbPrototypeLinkerService = PBPrototypeLinkerService(); @@ -103,8 +105,7 @@ class Interpret { } Future _generateScreen(DesignScreen designScreen) async { - var currentContext = - PBContext(PBConfiguration.fromJson(MainInfo().configurations)); + var currentContext = PBContext(configuration); var parentComponent = designScreen.designNode; diff --git a/lib/controllers/main_info.dart b/lib/controllers/main_info.dart index 47e4d617..75bfae95 100644 --- a/lib/controllers/main_info.dart +++ b/lib/controllers/main_info.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:sentry/sentry.dart'; class MainInfo { @@ -16,7 +17,7 @@ class MainInfo { /// Current working directory; contains the path from where the script was called Directory cwd; - Map configurations; + PBConfiguration configuration; // the type of configuration you want to set, 'default' is default type. String configurationType; @@ -36,14 +37,6 @@ class MainInfo { /// Boolean that indicates whether a `styles` document is created. bool exportStyles; - Map defaultConfigs = { - 'widgetStyle': 'Material', - 'widgetType': 'Stateless', - 'widgetSpacing': 'Expanded', - 'layoutPrecedence': ['columns', 'rows', 'stack'], - 'state-management': 'None' - }; - Map pbdf; factory MainInfo() { diff --git a/lib/controllers/sketch_controller.dart b/lib/controllers/sketch_controller.dart index 2e4f0d67..5ba88eba 100644 --- a/lib/controllers/sketch_controller.dart +++ b/lib/controllers/sketch_controller.dart @@ -19,14 +19,11 @@ class SketchController extends Controller { void convertFile( var fileAbsPath, var projectPath, - var configurationPath, - var configType, { + configuration, { bool jsonOnly = false, DesignProject designProject, AssetProcessingService apService, }) async { - configure(configurationPath, configType); - ///INTAKE var ids = InputDesignService(fileAbsPath, jsonOnly: jsonOnly); var sketchProject = generateSketchNodeTree( @@ -37,8 +34,7 @@ class SketchController extends Controller { super.convertFile( fileAbsPath, projectPath, - configurationPath, - configType, + configuration, designProject: sketchProject, jsonOnly: jsonOnly, apService: apService, diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index 3d3e169d..f130a6b6 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -1,5 +1,7 @@ import 'dart:convert'; import 'dart:io'; +import 'package:path/path.dart' as p; + import 'package:archive/archive.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; @@ -22,28 +24,15 @@ class FlutterProjectBuilder { var log = Logger('Project Builder'); + PBPageWriter pageWriter; + ///The [GenerationConfiguration] that is going to be use in the generation of the code /// ///This is going to be defaulted to [GenerationConfiguration] if nothing else is specified. GenerationConfiguration generationConfiguration; - Map configurations = { - 'provider': ProviderGenerationConfiguration(), - 'bloc': BLoCGenerationConfiguration(), - 'riverpod': RiverpodGenerationConfiguration(), - 'none': StatefulGenerationConfiguration(), - }; - - final DEFAULT_CONFIGURATION = StatefulGenerationConfiguration(); - - PBPageWriter pageWriter; - - FlutterProjectBuilder({this.project, this.pageWriter}) { - generationConfiguration = configurations[MainInfo() - .configurations['state-management'] - .toString() - .toLowerCase()] ?? - DEFAULT_CONFIGURATION; + FlutterProjectBuilder(this.generationConfiguration, + {this.project, this.pageWriter}) { generationConfiguration.pageWriter = pageWriter; } @@ -65,7 +54,7 @@ class FlutterProjectBuilder { log.error(error.toString()); } - await Directory('${pathToFlutterProject}assets/images') + await Directory(p.join(pathToFlutterProject, 'assets/images')) .create(recursive: true) .then((value) => { // print(value), @@ -129,14 +118,6 @@ class FlutterProjectBuilder { await generationConfiguration .generatePlatformAndOrientationInstance(project); - var l = File('${pathToFlutterProject}lib/main.dart').readAsLinesSync(); - var s = File('${pathToFlutterProject}lib/main.dart') - .openWrite(mode: FileMode.write, encoding: utf8); - for (var i = 0; i < l.length; i++) { - s.writeln(l[i]); - } - await s.close(); - Process.runSync( '${MainInfo().cwd.path}/lib/generation/helperScripts/shell-proxy.sh', ['rm -rf .dart_tool/build'], diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 82e6dd19..d392cb2a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -72,7 +72,7 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { return 'if(${platforms[0]} != null){return ${platforms[0]}Widget;}'; } // Get breakpoints from configurations and sort by value - var breakpoints = MainInfo().configurations['breakpoints']; + var breakpoints = MainInfo().configuration.breakpoints; if (breakpoints == null) { // TODO: Handle breakpoints being null breakpoints = {}; diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.dart b/lib/interpret_and_optimize/helpers/pb_configuration.dart index 1b2b4295..86dfe70a 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.dart @@ -1,8 +1,35 @@ +import 'package:path/path.dart' as p; + import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart'; part 'pb_configuration.g.dart'; -@JsonSerializable(nullable: true) +@JsonSerializable(nullable: true, ignoreUnannotated: true) class PBConfiguration { + static final Map availableGenConfigs = { + 'provider': ProviderGenerationConfiguration(), + 'bloc': BLoCGenerationConfiguration(), + 'riverpod': RiverpodGenerationConfiguration(), + 'none': StatefulGenerationConfiguration(), + }; + + ///The [GenerationConfiguration] that is going to be use in the generation of the code + /// + ///This is going to be defaulted to [GenerationConfiguration] if nothing else is specified. + GenerationConfiguration generationConfiguration; + + String platform; + + String projectName; + + String outputDirPath; + + String get genProjectPath => p.join(outputDirPath, projectName); + @JsonKey(defaultValue: 'Material') final String widgetStyle; @@ -18,11 +45,35 @@ class PBConfiguration { @JsonKey(defaultValue: ['column', 'row', 'stack']) final List layoutPrecedence; - Map configurations; + @JsonKey(name: 'breakpoints') + final Map breakpoints; + PBConfiguration(this.widgetStyle, this.widgetType, this.widgetSpacing, - this.stateManagement, this.layoutPrecedence); + this.stateManagement, this.layoutPrecedence, this.breakpoints); + + /// Converting the [json] into a [PBConfiguration] object. + /// + /// The [generationConfiguration] is going to be set manually, by grabbing the + /// value that is comming from [stateManagement]. + factory PBConfiguration.fromJson(Map json) { + var configuration = _$PBConfigurationFromJson(json); + configuration.generationConfiguration = + availableGenConfigs[configuration.stateManagement.toLowerCase()]; + configuration.generationConfiguration ??= StatefulGenerationConfiguration(); + return configuration; + } - factory PBConfiguration.fromJson(Map json) => - _$PBConfigurationFromJson(json); + /// Generating the default configuration if there is no json file found for [PBConfiguration] + /// to take in. + factory PBConfiguration.genericConfiguration() { + var defaultConfigs = { + 'widgetStyle': 'Material', + 'widgetType': 'Stateless', + 'widgetSpacing': 'Expanded', + 'layoutPrecedence': ['columns', 'rows', 'stack'], + 'state-management': 'None' + }; + return PBConfiguration.fromJson(defaultConfigs); + } Map toJson() => _$PBConfigurationToJson(this); } diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart index b72abc75..f453cc0d 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart @@ -14,7 +14,8 @@ PBConfiguration _$PBConfigurationFromJson(Map json) { json['stateManagement'] as String ?? 'None', (json['layoutPrecedence'] as List)?.map((e) => e as String)?.toList() ?? ['column', 'row', 'stack'], - )..configurations = json['configurations'] as Map; + json['breakpoints'] as Map, + ); } Map _$PBConfigurationToJson(PBConfiguration instance) => @@ -24,5 +25,5 @@ Map _$PBConfigurationToJson(PBConfiguration instance) => 'widgetSpacing': instance.widgetSpacing, 'stateManagement': instance.stateManagement, 'layoutPrecedence': instance.layoutPrecedence, - 'configurations': instance.configurations, + 'breakpoints': instance.breakpoints, }; diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index e172dc89..88130e11 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -39,13 +39,15 @@ class PBPlatformOrientationLinkerService { // Add orientation builder template to the project // if there are more than 1 orientation on the project if (hasMultipleOrientations()) { - tree.rootNode.currentContext.project.genProjectData.commandQueue + tree.rootNode.currentContext.configuration.generationConfiguration + .commandQueue .add(OrientationBuilderCommand(tree.UUID)); } // Add responsive layout builder template to the project // if there are more than 1 plataform on the project if (hasMultiplePlatforms()) { - tree.rootNode.currentContext.project.genProjectData.commandQueue + tree.rootNode.currentContext.configuration.generationConfiguration + .commandQueue .add(ResponsiveLayoutBuilderCommand(tree.UUID)); _addBreakpoints(tree); } @@ -204,13 +206,13 @@ class PBPlatformOrientationLinkerService { } void _addBreakpoints(PBIntermediateTree tree) { - if (MainInfo().configurations.containsKey('breakpoints')) { - Map bp = - MainInfo().configurations['breakpoints'].cast(); + if (MainInfo().configuration.breakpoints != null) { + var bp = MainInfo().configuration.breakpoints.cast(); bp.forEach((key, value) { var cmd = AddConstantCommand( tree.UUID, key + 'Breakpoint', 'num', value.toString()); - tree.rootNode.currentContext.project.genProjectData.commandQueue + tree.rootNode.currentContext.configuration.generationConfiguration + .commandQueue .add(cmd); }); } diff --git a/lib/main.dart b/lib/main.dart index 2c416afe..b1df5bee 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/input/helper/azure_asset_service.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; import 'package:parabeac_core/input/sketch/services/input_design.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; import 'package:quick_log/quick_log.dart'; import 'package:sentry/sentry.dart'; @@ -17,6 +18,7 @@ import 'package:http/http.dart' as http; import 'package:args/args.dart'; import 'controllers/main_info.dart'; import 'package:yaml/yaml.dart'; +import 'package:path/path.dart' as p; ArgResults argResults; @@ -47,7 +49,8 @@ void main(List args) async { ..addOption('config-path', help: 'Path of the configuration file', abbr: 'c', - defaultsTo: 'default:lib/configurations/configurations.json') + defaultsTo: + '${p.setExtension(p.join('lib/configurations/', 'configurations'), '.json')}') ..addOption('fig', help: 'The ID of the figma file', abbr: 'f') ..addOption('figKey', help: 'Your personal API Key', abbr: 'k') ..addOption( @@ -80,14 +83,12 @@ ${parser.usage} exit(0); } + var configuration = + generateConfiguration(p.normalize(argResults['config-path'])); + // Detect platform - if (Platform.isMacOS || Platform.isLinux) { - MainInfo().platform = 'UIX'; - } else if (Platform.isWindows) { - MainInfo().platform = 'WIN'; - } else { - MainInfo().platform = 'OTH'; - } + MainInfo().platform = Platform.operatingSystem; + configuration.platform = Platform.operatingSystem; String path = argResults['path']; @@ -98,8 +99,8 @@ ${parser.usage} MainInfo().exportStyles = argResults['include-styles']; var jsonOnly = argResults['export-pbdl']; - var configurationPath = argResults['config-path']; - var configurationType = 'default'; + // var configurationPath = argResults['config-path']; + // var configurationType = 'default'; String projectName = argResults['project-name']; // Handle input errors @@ -117,25 +118,16 @@ ${parser.usage} designType = 'pbdl'; } - // usage -c "default:lib/configurations/configurations.json - var configSet = configurationPath.split(':'); - if (configSet.isNotEmpty) { - configurationType = configSet[0]; - } - if (configSet.length >= 2) { - // handle configurations - configurationPath = configSet[1]; - } - // Populate `MainInfo()` - MainInfo().outputPath = argResults['out']; + // If outputPath is empty, assume we are outputting to design file path - MainInfo().outputPath ??= await getCleanPath(path ?? Directory.current.path); - if (!MainInfo().outputPath.endsWith('/')) { - MainInfo().outputPath += '/'; - } + MainInfo().outputPath = (p.absolute( + p.normalize(argResults['out'] ?? p.dirname(path ?? Directory.current)))); + configuration.outputDirPath = MainInfo().outputPath; MainInfo().projectName = projectName; + configuration.projectName = projectName; + MainInfo().configuration = configuration; // Create pngs directory @@ -189,8 +181,7 @@ ${parser.usage} SketchController().convertFile( path, MainInfo().outputPath + projectName, - configurationPath, - configurationType, + configuration, jsonOnly: jsonOnly, apService: SketchAssetProcessor(), ); @@ -220,8 +211,7 @@ ${parser.usage} FigmaController().convertFile( jsonOfFigma, MainInfo().outputPath + projectName, - configurationPath, - configurationType, + configuration, jsonOnly: jsonOnly, apService: FigmaAssetProcessor(), ); @@ -244,8 +234,7 @@ ${parser.usage} DesignController().convertFile( pbdf, MainInfo().outputPath + projectName, - configurationPath, - configurationType, + configuration, ); } exitCode = 0; @@ -274,6 +263,24 @@ Future checkConfigFile() async { addToAmplitude(); } +/// Generating the [PBConfiguration] based in the configuration file in [path] +PBConfiguration generateConfiguration(String path) { + var configuration; + try { + ///SET CONFIGURATION + // Setting configurations globally + configuration = + PBConfiguration.fromJson(json.decode(File(path).readAsStringSync())); + } catch (e, stackTrace) { + MainInfo().sentry.captureException( + exception: e, + stackTrace: stackTrace, + ); + } + configuration ??= PBConfiguration.genericConfiguration(); + return configuration; +} + /// Gets the homepath of the user according to their OS String getHomePath() { var envvars = Platform.environment; @@ -309,21 +316,6 @@ void addToAmplitude() async { ); } -Future getCleanPath(String path) async { - if (path == null || path.isEmpty) { - return ''; - } - var list = path.split('/'); - if (!await Directory(path).exists()) { - list.removeLast(); - } - var result = ''; - for (var dir in list) { - result += dir + '/'; - } - return result; -} - /// Returns true if `args` contains two or more /// types of intake to parabeac-core bool hasTooManyArgs(ArgResults args) { diff --git a/test/lib/interpret_and_optimize/services/interpret_test.dart b/test/lib/interpret_and_optimize/services/interpret_test.dart index 3af8271e..eb8a0f98 100644 --- a/test/lib/interpret_and_optimize/services/interpret_test.dart +++ b/test/lib/interpret_and_optimize/services/interpret_test.dart @@ -72,7 +72,7 @@ void main() { setUp(() { Interpret().init( '${Directory.current.path}/test/lib/interpret_and_optimize/services'); - MainInfo().configurations = MainInfo().defaultConfigs; + MainInfo().configurationType = 'default'; project = MockProject(); From ecdeee13bda40c82bd143a45df0a4cf2cf96d87d Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 2 Jun 2021 18:58:25 -0600 Subject: [PATCH 176/404] Merge `dev` into `feat/responsive-ui`. Add `masterNode` property to `PBContext` since `GeneratorContext` was removed. --- lib/design_logic/pb_fill.dart | 4 +- lib/design_logic/pb_shared_master_node.dart | 2 +- .../flutter_project_builder.dart | 54 ++++- .../import_helper.dart | 9 + .../attribute-helper/pb_color_gen_helper.dart | 74 +++++-- .../generators/middleware/middleware.dart | 11 +- .../state_management/bloc_middleware.dart | 3 +- .../state_management/provider_middleware.dart | 30 +-- .../state_management/riverpod_middleware.dart | 7 +- .../state_management/stateful_middleware.dart | 5 +- .../utils/middleware_utils.dart | 18 +- .../symbols/pb_instancesym_gen.dart | 188 +++++++++++------- .../generators/symbols/pb_mastersym_gen.dart | 4 + .../util/pb_generation_view_data.dart | 2 + .../generators/util/pb_input_formatter.dart | 9 + .../provider_file_structure_strategy.dart | 4 - .../provider_generation_configuration.dart | 3 +- .../bloc_state_template_strategy.dart | 3 + .../stateful_template_strategy.dart | 2 + .../stateless_template_strategy.dart | 6 +- .../visual-widgets/pb_container_gen.dart | 3 +- lib/input/figma/entities/layers/instance.dart | 4 +- .../figma/entities/style/figma_fill.dart | 3 + .../sketch/entities/layers/symbol_master.dart | 2 +- lib/input/sketch/entities/style/fill.dart | 3 +- .../sketch/entities/style/shared_style.dart | 100 +++++++--- lib/input/sketch/entities/style/style.dart | 10 +- lib/input/sketch/helper/sketch_project.dart | 22 +- .../sketch/helper/symbol_node_mixin.dart | 33 +-- .../entities/inherited_container.dart | 6 + .../entities/pb_shared_instance.dart | 12 +- .../entities/pb_shared_master_node.dart | 18 +- .../helpers/pb_context.dart | 2 + .../pb_shared_aggregation_service.dart | 11 +- .../intermediate_auxillary_data.dart | 4 + .../pb_symbol_instance_overridable_value.dart | 4 + lib/main.dart | 6 +- test/assets/SymbolTest-simp.sketch | Bin 36255 -> 26493 bytes 38 files changed, 466 insertions(+), 215 deletions(-) diff --git a/lib/design_logic/pb_fill.dart b/lib/design_logic/pb_fill.dart index 33861d56..35113753 100644 --- a/lib/design_logic/pb_fill.dart +++ b/lib/design_logic/pb_fill.dart @@ -3,7 +3,9 @@ import 'package:parabeac_core/design_logic/color.dart'; abstract class PBFill { PBColor color; bool isEnabled; - PBFill(this.color, [this.isEnabled = true]); + int fillType; + + PBFill(this.color, this.fillType, [this.isEnabled = true]); toJson(); } diff --git a/lib/design_logic/pb_shared_master_node.dart b/lib/design_logic/pb_shared_master_node.dart index a6403b91..d0931d6f 100644 --- a/lib/design_logic/pb_shared_master_node.dart +++ b/lib/design_logic/pb_shared_master_node.dart @@ -90,7 +90,7 @@ class PBSharedMasterDesignNode extends DesignNode var sharedParameters = []; for (var prop in overrideProperties) { if (!ovrNames.contains(prop.overrideName)) { - var properties = AddMasterSymbolName(prop.overrideName, children); + var properties = AddMasterSymbolOverrideName(prop.overrideName, children); sharedParameters.add(PBSharedParameterProp( properties['name'], properties['type'], diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index b8fbde97..7a7df65a 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -111,12 +111,15 @@ class FlutterProjectBuilder { try { Directory('${pathToFlutterProject}lib/document/') .createSync(recursive: true); + + WriteStyleClasses(); + var s = File('${pathToFlutterProject}lib/document/shared_props.g.dart') .openWrite(mode: FileMode.write, encoding: utf8); s.write('''import 'dart:ui'; import 'package:flutter/material.dart'; - + import 'Styles.g.dart'; '''); for (var sharedStyle in mainTree.sharedStyles) { s.write(sharedStyle.generate() + '\n'); @@ -157,9 +160,9 @@ class FlutterProjectBuilder { log.info( Process.runSync( - 'dartfmt', + 'dart', [ - '-w', + 'format', '${pathToFlutterProject}bin', '${pathToFlutterProject}lib', '${pathToFlutterProject}test' @@ -169,3 +172,48 @@ class FlutterProjectBuilder { ); } } + +void WriteStyleClasses() +{ + var s = File('${pathToFlutterProject}lib/document/Styles.g.dart') + .openWrite(mode: FileMode.write, encoding: utf8); + s.write(''' +import 'dart:ui'; +import 'package:flutter/material.dart'; + +class SK_Fill { + Color color; + bool isEnabled; + SK_Fill(this.color, [this.isEnabled = true]); +} + +class SK_Border { + bool isEnabled; + double fillType; + Color color; + double thickness; + SK_Border(this.isEnabled, this.fillType, this.color, this.thickness); +} + +class SK_BorderOptions { + bool isEnabled; + List dashPattern; + int lineCapStyle; + int lineJoinStyle; + SK_BorderOptions(this.isEnabled, this.dashPattern, this.lineCapStyle, this.lineJoinStyle); +} + +class SK_Style { + Color backgroundColor; + List fills; + List borders; + SK_BorderOptions borderOptions; + TextStyle textStyle; + bool hasShadow; + SK_Style(this.backgroundColor, this.fills, this.borders, this.borderOptions,this.textStyle, [this.hasShadow = false]); +} +'''); + + s.close(); + +} diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 3fd08983..ef6ade8c 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/generation/flutter_project_builder/file_writer_observer.dart'; +import 'package:recase/recase.dart'; class ImportHelper implements FileWriterObserver { final Map imports = {}; @@ -79,4 +80,12 @@ class ImportHelper implements FileWriterObserver { imports[fileUUID] = filePath; } } + + static String getName(String name) { + var index = name.indexOf('/'); + // Remove everything after the /. So if the name is SignUpButton/Default, we end up with SignUpButton as the name we produce. + return index < 0 + ? name + : name.replaceRange(index, name.length, '').pascalCase; + } } diff --git a/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart index c67ff07f..53ac5b20 100644 --- a/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart @@ -13,29 +13,69 @@ class PBColorGenHelper extends PBAttributesHelper { if (source == null) { return statement; } - if (source is InheritedScaffold) { - var scaffold = source; - if (scaffold.auxiliaryData.color == null) { + if (source.auxiliaryData.style != null) { + if (source is InheritedScaffold) { + var scaffold = source; + if (scaffold.auxiliaryData.color == null) { + statement = ''; + } else { + statement = findDefaultColor(scaffold.auxiliaryData.color) != null + ? 'backgroundColor: ${findDefaultColor( + scaffold.auxiliaryData.color)},\n' + : 'backgroundColor: Color(${scaffold + .auxiliaryData.color}),\n'; + } + } else if (source.auxiliaryData.color == null) { statement = ''; } else { - statement = findDefaultColor(scaffold.auxiliaryData.color) != null - ? 'backgroundColor: ${findDefaultColor(scaffold.auxiliaryData.color)},' - : 'backgroundColor: Color(${scaffold.auxiliaryData.color}),\n'; + if (source is! InheritedContainer) { + statement = findDefaultColor(source.auxiliaryData.color) != null + ? 'color: ${findDefaultColor( + source.auxiliaryData.color)},\n' + : 'color: Color(${source + .auxiliaryData.color}),\n'; + } else if ((source as InheritedContainer).isBackgroundVisible) { + statement = findDefaultColor(source.auxiliaryData.color) != null + ? 'color: ${findDefaultColor( + source.auxiliaryData.color)},\n' + : 'color: Color(${source + .auxiliaryData.color}),\n'; + } else { + statement = ''; + } } - } else if (source.auxiliaryData.color == null) { - statement = ''; } else { - if (source is! InheritedContainer) { - statement = findDefaultColor(source.auxiliaryData.color) != null - ? 'color: ${findDefaultColor(source.auxiliaryData.color)},' - : 'color: Color(${source.auxiliaryData.color}),\n'; - } else if ((source as InheritedContainer).isBackgroundVisible) { - statement = findDefaultColor(source.auxiliaryData.color) != null - ? 'color: ${findDefaultColor(source.auxiliaryData.color)},' - : 'color: Color(${source.auxiliaryData.color}),\n'; - } else { + if (source is InheritedScaffold) { + var scaffold = source; + if (scaffold.auxiliaryData.color == null) { + statement = ''; + } else { + statement = findDefaultColor(scaffold.auxiliaryData.color) != null + ? 'backgroundColor: ${findDefaultColor( + scaffold.auxiliaryData.color)},\n' + : 'backgroundColor: Color(${scaffold + .auxiliaryData.color}),\n'; + } + } else if (source.auxiliaryData.color == null) { statement = ''; + } else { + if (source is! InheritedContainer) { + statement = findDefaultColor(source.auxiliaryData.color) != null + ? 'color: ${findDefaultColor( + source.auxiliaryData.color)},\n' + : 'color: Color(${source + .auxiliaryData.color}),\n'; + } else if ((source as InheritedContainer).isBackgroundVisible) { + statement = findDefaultColor(source.auxiliaryData.color) != null + ? 'color: ?? ${findDefaultColor( + source.auxiliaryData.color)},\n' + : 'color: Color(${source + .auxiliaryData.color}),\n'; + } else { + statement = ''; + } } + } return statement; } diff --git a/lib/generation/generators/middleware/middleware.dart b/lib/generation/generators/middleware/middleware.dart index 486f9400..d668962f 100644 --- a/lib/generation/generators/middleware/middleware.dart +++ b/lib/generation/generators/middleware/middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; @@ -10,15 +11,7 @@ abstract class Middleware { Middleware(this.generationManager); - String getNameOfNode(PBIntermediateNode node) => getName(node.name); - - String getName(String name) { - var index = name.indexOf('/'); - // Remove everything after the /. So if the name is SignUpButton/Default, we end up with SignUpButton as the name we produce. - return index < 0 - ? name - : name.replaceRange(index, name.length, '').pascalCase; - } + String getNameOfNode(PBIntermediateNode node) => ImportHelper.getName(node.name); Future applyMiddleware(PBIntermediateNode node) => Future.value(node); diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 8b7f481b..feab4dba 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -136,6 +137,6 @@ class BLoCMiddleware extends Middleware { PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); return fileStrategy.GENERATED_PROJECT_PATH + fileStrategy.RELATIVE_VIEW_PATH + - '${generalStateName.snakeCase}_bloc/${getName(symbolMaster.name).snakeCase}_bloc.dart'; + '${generalStateName.snakeCase}_bloc/${ImportHelper.getName(symbolMaster.name).snakeCase}_bloc.dart'; } } diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 445761b5..42e2674c 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -2,10 +2,8 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.d import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; -import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; @@ -33,30 +31,20 @@ class ProviderMiddleware extends Middleware { .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); managerData.addImport('package:provider/provider.dart'); watcherName = getVariableName(node.name.snakeCase + '_notifier'); - var widgetName = node.functionCallName.camelCase; - var watcher; - - if (node.currentContext.tree.rootNode.generator.templateStrategy - is StatelessTemplateStrategy) { - watcher = PBVariable(watcherName, 'final ', true, - '${getName(node.functionCallName).pascalCase}().$widgetName'); - managerData.addGlobalVariable(watcher); - } addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); PBGenCache().appendToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy, generateModelPath: false)); if (node.generator is! StringGeneratorAdapter) { - var modelName = getName(node.functionCallName).pascalCase; - var defaultWidget = node.functionCallName.pascalCase; + var modelName = ImportHelper.getName(node.functionCallName).pascalCase; var providerWidget = ''' ChangeNotifierProvider( create: (context) => $modelName(), child: LayoutBuilder( builder: (context, constraints) { - var widget = $defaultWidget(constraints); + var widget = ${MiddlewareUtils.generateVariableBody(node)}; context .read<$modelName>() @@ -65,10 +53,10 @@ class ProviderMiddleware extends Middleware { return GestureDetector( onTap: () => context.read< - $modelName>(), // TODO: add your method to change the state here - child: context - .watch<$modelName>() - .currentWidget, + ${modelName}>().onGesture(), + child: Consumer<$modelName>( + builder: (context, ${modelName.toLowerCase()}, child) => ${modelName.toLowerCase()}.currentWidget + ), ); }, ), @@ -80,7 +68,7 @@ class ProviderMiddleware extends Middleware { } watcherName = getNameOfNode(node); - var parentDirectory = getName(node.name).snakeCase; + var parentDirectory = ImportHelper.getName(node.name).snakeCase; // Generate model's imports var modelGenerator = PBFlutterGenerator(ImportHelper(), @@ -116,8 +104,8 @@ class ProviderMiddleware extends Middleware { var symbolMaster = PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); var import = generateModelPath - ? '${fileStrategy.RELATIVE_MODEL_PATH}${getName(symbolMaster.name).snakeCase}.dart' - : '${fileStrategy.RELATIVE_VIEW_PATH}${getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; + ? '${fileStrategy.RELATIVE_MODEL_PATH}${ImportHelper.getName(symbolMaster.name).snakeCase}.dart' + : '${fileStrategy.RELATIVE_VIEW_PATH}${ImportHelper.getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; return fileStrategy.GENERATED_PROJECT_PATH + import; } } diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 8984811e..6470c1fa 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -30,7 +31,7 @@ class RiverpodMiddleware extends Middleware { managerData.addImport('package:flutter_riverpod/flutter_riverpod.dart'); watcherName = getVariableName(node.functionCallName.snakeCase); var watcher = PBVariable(watcherName + '_provider', 'final ', true, - 'ChangeNotifierProvider((ref) => ${getName(node.functionCallName).pascalCase}())'); + 'ChangeNotifierProvider((ref) => ${ImportHelper.getName(node.functionCallName).pascalCase}())'); if (node.currentContext.tree.rootNode.generator.templateStrategy is StatelessTemplateStrategy) { @@ -54,7 +55,7 @@ class RiverpodMiddleware extends Middleware { generationManager, node, ); - fileStrategy.writeRiverpodModelFile(code, getName(node.name).snakeCase); + fileStrategy.writeRiverpodModelFile(code, ImportHelper.getName(node.name).snakeCase); return node; } @@ -75,6 +76,6 @@ class RiverpodMiddleware extends Middleware { PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); return fileStrategy.GENERATED_PROJECT_PATH + fileStrategy.RELATIVE_MODEL_PATH + - '${getName(symbolMaster.name).snakeCase}.dart'; + '${ImportHelper.getName(symbolMaster.name).snakeCase}.dart'; } } diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index ab7aa726..dffd10ea 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; @@ -20,7 +21,7 @@ class StatefulMiddleware extends Middleware { return node; } var states = [node]; - var parentDirectory = getName(node.name).snakeCase; + var parentDirectory = ImportHelper.getName(node.name).snakeCase; node?.auxiliaryData?.stateGraph?.states?.forEach((state) { states.add(state.variation.node); @@ -43,6 +44,6 @@ class StatefulMiddleware extends Middleware { PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); return fileStrategy.GENERATED_PROJECT_PATH + fileStrategy.RELATIVE_VIEW_PATH + - '${getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; + '${ImportHelper.getName(symbolMaster.name).snakeCase}/${node.functionCallName.snakeCase}.dart'; } } diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 75ddef51..6f46de3d 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -17,9 +18,9 @@ class MiddlewareUtils { if (node is PBSharedMasterNode && (node.overridableProperties?.isNotEmpty ?? false)) { - node.overridableProperties.forEach((property) { - overrideVars += 'final ${property.friendlyName};'; - overrideAttr += 'this.${property.friendlyName}, '; + node.overridableProperties.forEach((prop) { + overrideVars += 'final ${prop.friendlyName};'; + overrideAttr += 'this.${prop.friendlyName}, '; }); stateBuffer.write(MiddlewareUtils.generateEmptyVariable(node)); stateInitializers.write( @@ -33,9 +34,10 @@ class MiddlewareUtils { if (variationNode is PBSharedMasterNode && (variationNode.overridableProperties?.isNotEmpty ?? false)) { - variationNode.overridableProperties.forEach((property) { - overrideVars += 'final ${property.friendlyName};'; - overrideAttr += 'this.${property.friendlyName}, '; + variationNode.overridableProperties.forEach((prop) { + var friendlyName = SN_UUIDtoVarName[prop.propertyName] ?? 'NOTFOUND'; + overrideVars += 'final $friendlyName;'; + overrideAttr += 'this.$friendlyName, '; }); stateBuffer.write(MiddlewareUtils.generateEmptyVariable(variationNode)); stateInitializers.write( @@ -78,6 +80,10 @@ class MiddlewareUtils { Widget currentWidget; $defaultStateName(){} + // default provider event handler for gestures. + void onGesture() { + } + void setCurrentWidget(Widget currentWidget) { this.currentWidget = currentWidget; } diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index fbd197fc..92c8fe41 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -1,6 +1,9 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; +import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/entities/style/text_style.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; @@ -10,6 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; +import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; import 'package:quick_log/quick_log.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:recase/recase.dart'; @@ -22,57 +26,21 @@ class PBSymbolInstanceGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is PBSharedInstanceIntermediateNode) { - var method_signature = source.functionCallName?.pascalCase; - if (method_signature == null) { - log.error(' Could not find master name on: $source'); - return 'Container(/** This Symbol was not found **/)'; - } - - var overrideProp = SN_UUIDtoVarName[source.UUID + '_symbolID']; - - method_signature = PBInputFormatter.formatLabel(method_signature, - destroyDigits: false, spaceToUnderscore: false, isTitle: true); var buffer = StringBuffer(); - buffer.write('LayoutBuilder( \n'); buffer.write(' builder: (context, constraints) {\n'); buffer.write(' return '); - if (overrideProp != null) { - buffer.write('$overrideProp ?? '); - } + // If storage found an instance, get its master + var masterSymbol = + PBSymbolStorage().getSharedMasterNodeBySymbolID(source.SYMBOL_ID); - buffer.write(method_signature); - buffer.write('('); - buffer.write('constraints,'); + // recursively generate Symbol Instance constructors with overrides + buffer.write(genSymbolInstance(source.UUID, source.overrideValuesMap, + masterSymbol.parametersDefsMap, source.managerData)); - for (var param in source.sharedParamValues ?? []) { - switch (param.type) { - case PBSharedInstanceIntermediateNode: - var siString = genSymbolInstance( - param.UUID, param.value, source.overrideValues); - if (siString != '') { - buffer.write('${param.name}: '); - buffer.write(siString); - } - break; - case InheritedBitmap: - buffer.write('${param.name}: \"assets/${param.value["_ref"]}\",'); - break; - case TextStyle: - // hack to include import - source.currentContext.tree.data.addImport( - 'package:${MainInfo().projectName}/document/shared_props.g.dart'); - buffer.write( - '${param.name}: ${SharedStyle_UUIDToName[param.value] ?? "TextStyle()"},'); - break; - default: - buffer.write('${param.name}: \"${param.value}\",'); - break; - } - } - // end of return function(); - buffer.write(');\n'); + // end of return (); + buffer.write(';\n'); // end of builder: (context, constraints) { buffer.write('}\n'); // end of LayoutBuilder() @@ -82,13 +50,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { return ''; } - String genSymbolInstance(String overrideUUID, String UUID, - List overrideValues, - {int depth = 1}) { - if ((UUID == null) || (UUID == '')) { - return ''; - } - + PBSharedMasterNode getMasterSymbol(String UUID) { var masterSymbol; var nodeFound = PBSymbolStorage().getAllSymbolById(UUID); if (nodeFound is PBSharedMasterNode) { @@ -101,43 +63,119 @@ class PBSymbolInstanceGenerator extends PBGenerator { // Try to find master by looking for the master's SYMBOL_ID masterSymbol = PBSymbolStorage().getSharedMasterNodeBySymbolID(UUID); } - // file could have override names that don't exist? That's really odd, but we have a file that does that. - if (masterSymbol == null) { + + return masterSymbol; + } + + String genSymbolInstance( + String UUID, + Map mapOverrideValues, + Map mapParameterValues, + PBGenerationViewData managerData, + { bool topLevel = true, + String UUIDPath = ''}) { + if ((UUID == null) || (UUID == '')) { return ''; } - assert( - masterSymbol != null, 'Could not find master symbol with UUID: $UUID'); var buffer = StringBuffer(); - buffer.write('${masterSymbol.friendlyName}(constraints, '); - for (var ovrValue in overrideValues) { - var ovrUUIDStrings = ovrValue.UUID.split('/'); - if ((ovrUUIDStrings.length == depth + 1) && - (ovrUUIDStrings[depth - 1] == overrideUUID)) { - var ovrUUID = ovrUUIDStrings[depth]; - switch (ovrValue.type) { + var masterSymbol = getMasterSymbol(UUID); + + // file could have override names that don't exist? That's really odd, but we have a file that does that. + if (masterSymbol == null) { + log.error(' Could not find master symbol for UUID:: $UUID'); + return 'Container(/** This Symbol was not found **/)});'; + } + + var symName = masterSymbol.name.snakeCase; + if (symName == null) { + log.error(' Could not find master name on: $masterSymbol'); + return 'Container(/** This Symbol was not found **/)});'; + } + + symName = PBInputFormatter.formatLabel(symName, + destroyDigits: false, spaceToUnderscore: false, isTitle: true); + + var path = 'symbols'; + if (masterSymbol.name.contains('/')) { + path = ImportHelper + .getName(masterSymbol.name) + .snakeCase; + } + managerData.addImport( + 'package:${MainInfo().projectName}/view/$path/${symName.snakeCase}.dart'); + + // if this symbol is overridable, then put variable name + null check + var overrideProp = SN_UUIDtoVarName[UUID + '_symbolID']; + if (overrideProp != null) { + buffer.write('$overrideProp ?? '); + } + + buffer.write(symName.pascalCase); + buffer.write('(\n'); + buffer.write('constraints,\n'); + + // need to iterate through master symbol parametersDefsMap to pass parent variables down to children + + masterSymbol.parametersDefsMap.forEach((overrideName, smParameter) { + var ovrValue = ''; + overrideName = UUIDPath + overrideName; + if (mapOverrideValues.containsKey(overrideName)) { + var param = mapOverrideValues[overrideName]; + switch (param.type) { case PBSharedInstanceIntermediateNode: - buffer.write(genSymbolInstance( - ovrValue.value, ovrUUID, overrideValues, - depth: depth + 1)); + ovrValue = genSymbolInstance( + param.value, + mapOverrideValues, + mapParameterValues, + managerData, + topLevel: false, + UUIDPath: '$UUIDPath${param.UUID}/', + ); break; case InheritedBitmap: - var name = SN_UUIDtoVarName[ovrUUID + '_image']; - buffer.write('$name: \"assets/${ovrValue.value["_ref"]}\",'); + ovrValue = '\"assets/${param.value["_ref"]}\"'; break; case TextStyle: - var name = SN_UUIDtoVarName[ovrUUID + '_textStyle']; - buffer.write( - '$name: ${SharedStyle_UUIDToName[ovrValue.value] ?? "TextStyle()"},'); + // hack to include import + managerData.addImport( + 'package:${MainInfo().projectName}/document/shared_props.g.dart'); + ovrValue = '${SharedStyle_UUIDToName[param.value]}.textStyle'; break; - default: - var name = SN_UUIDtoVarName[ovrUUID]; - buffer.write('$name: \"${ovrValue.value}\",'); + case Style: + // hack to include import + managerData.addImport( + 'package:${MainInfo().projectName}/document/shared_props.g.dart'); + ovrValue = '${SharedStyle_UUIDToName[param.value]}'; + break; + case String: + ovrValue = '\"${param.value}\"'; break; + default: + log.info( + 'Unknown type ${param.type.toString()} in parameter values for symbol instance.\n'); } } - } - buffer.write('),'); + // get parameter name to pass to widget constructor + var friendlyName = SN_UUIDtoVarName[ + PBInputFormatter.findLastOf(smParameter.propertyName, '/')]; + var paramName = ''; + // check if parent widget has parameter to pass down to children + if (managerData.hasParams && + mapParameterValues.containsKey(smParameter.propertyName)) { + // yes, so pass down with optional null check + paramName = friendlyName; + if (ovrValue != '') { + paramName += ' ?? '; + } + } + if ((ovrValue != '') || (paramName != '')) { + buffer.write('$friendlyName: $paramName$ovrValue,\n'); + } + }); + + buffer.write(')\n'); + return buffer.toString(); } } diff --git a/lib/generation/generators/symbols/pb_mastersym_gen.dart b/lib/generation/generators/symbols/pb_mastersym_gen.dart index 3253378f..0a1c2e7a 100644 --- a/lib/generation/generators/symbols/pb_mastersym_gen.dart +++ b/lib/generation/generators/symbols/pb_mastersym_gen.dart @@ -17,11 +17,15 @@ class PBMasterSymbolGenerator extends PBGenerator { if (source.child == null) { return ''; } + // override styles if need be. + generatorContext.masterNode = source; + source.child.currentContext = source.currentContext; // see if widget itself is overridden, need to pass var generatedWidget = source.child.generator.generate(source.child, generatorContext); + generatorContext.masterNode = null; if (generatedWidget == null || generatedWidget.isEmpty) { return ''; } diff --git a/lib/generation/generators/util/pb_generation_view_data.dart b/lib/generation/generators/util/pb_generation_view_data.dart index 02464c53..2691484b 100644 --- a/lib/generation/generators/util/pb_generation_view_data.dart +++ b/lib/generation/generators/util/pb_generation_view_data.dart @@ -9,6 +9,8 @@ class PBGenerationViewData { final Set _imports = {}; final Set _toDispose = {}; bool _isDataLocked = false; + bool hasParams = false; + PLATFORM platform; ORIENTATION orientation; diff --git a/lib/generation/generators/util/pb_input_formatter.dart b/lib/generation/generators/util/pb_input_formatter.dart index 0aab286d..6744e40f 100644 --- a/lib/generation/generators/util/pb_input_formatter.dart +++ b/lib/generation/generators/util/pb_input_formatter.dart @@ -45,4 +45,13 @@ class PBInputFormatter { str.startsWith(RegExp(r'^[\d]+')) ? str.replaceFirstMapped(RegExp(r'^[\d]+'), (e) => '') : str; + + /// Method that splits `target` according to `delimeter` + /// and returns the last entry in the list. + static String findLastOf(String target, String delimeter) { + if (target == null || delimeter == null) { + return ''; + } + return target.split(delimeter).last; + } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart index af85f667..99ee86de 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart @@ -5,15 +5,12 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; class ProviderFileStructureStrategy extends FileStructureStrategy { - final RELATIVE_PROVIDER_PATH = 'lib/providers/'; final RELATIVE_MODEL_PATH = 'lib/models/'; - var _providersPath; var _modelsPath; ProviderFileStructureStrategy( String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) : super(genProjectPath, pageWriter, pbProject) { - _providersPath = '$genProjectPath$RELATIVE_PROVIDER_PATH'; _modelsPath = '$genProjectPath$RELATIVE_MODEL_PATH'; } @@ -27,7 +24,6 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { } Future _generateMissingDirectories() async { - Directory(_providersPath).createSync(recursive: true); Directory(_modelsPath).createSync(recursive: true); } diff --git a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart index a0fded5b..d5978fef 100644 --- a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/provider_middleware.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; @@ -50,7 +51,7 @@ class ProviderGenerationConfiguration extends GenerationConfiguration { node = await it.current.applyMiddleware(node); if (it.current is ProviderMiddleware && node is PBSharedInstanceIntermediateNode) { - registeredModels.add(it.current.getName(node.functionCallName)); + registeredModels.add(ImportHelper.getName(node.functionCallName)); } } return node; diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index ccf3b2a8..ecf1d718 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -14,7 +15,9 @@ class BLoCStateTemplateStrategy extends TemplateStrategy { PBContext generatorContext, {args}) { var widgetName = retrieveNodeName(node); + node.managerData.hasParams = true; var returnStatement = node.generator.generate(node, generatorContext); + node.managerData.hasParams = false; var overrides = ''; var overrideVars = ''; if (node is PBSharedMasterNode && node.overridableProperties.isNotEmpty) { diff --git a/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart index 8d63380f..d353f8f2 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateful_template_strategy.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -12,6 +13,7 @@ class StatefulTemplateStrategy extends TemplateStrategy { var widgetName = retrieveNodeName(node); var constructorName = '$widgetName'; var returnStatement = node.generator.generate(node, generatorContext); + return ''' ${manager.generateImports()} diff --git a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart index 82692712..c02f663a 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -11,9 +12,12 @@ class StatelessTemplateStrategy extends TemplateStrategy { PBContext generatorContext, {args}) { var widgetName = node.name; + node.managerData.hasParams = true; var returnStatement = node.generator.generate(node, generatorContext); + node.managerData.hasParams = false; var overrides = ''; var overrideVars = ''; + if (node is PBSharedMasterNode && node.overridableProperties.isNotEmpty) { node.overridableProperties.forEach((prop) { overrides += 'this.${prop.friendlyName}, '; @@ -21,7 +25,7 @@ class StatelessTemplateStrategy extends TemplateStrategy { }); } return ''' -${manager.generateImports()} + ${manager.generateImports()} class ${widgetName.pascalCase} extends StatelessWidget{ ${node is PBSharedMasterNode ? 'final constraints;' : ''} diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index 2678188d..ba7391bc 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -21,7 +21,8 @@ class PBContainerGenerator extends PBGenerator { if (source.auxiliaryData.borderInfo != null && source.auxiliaryData.borderInfo.isNotEmpty) { buffer.write(PBBoxDecorationHelper().generate(source, generatorContext)); - } else { + } + else { buffer.write(PBColorGenHelper().generate(source, generatorContext)); } diff --git a/lib/input/figma/entities/layers/instance.dart b/lib/input/figma/entities/layers/instance.dart index 6c5d419b..d8694fa9 100644 --- a/lib/input/figma/entities/layers/instance.dart +++ b/lib/input/figma/entities/layers/instance.dart @@ -106,8 +106,8 @@ class Instance extends FigmaFrame String pbdfType = 'symbol_instance'; @override - Map AddMasterSymbolName(String overrideName, List children) { - // TODO: implement AddMasterSymbolName + Map AddMasterSymbolOverrideName(String overrideName, List children) { + // TODO: implement AddMasterSymbolOverrideName throw UnimplementedError(); } diff --git a/lib/input/figma/entities/style/figma_fill.dart b/lib/input/figma/entities/style/figma_fill.dart index 814fcfb4..93a81946 100644 --- a/lib/input/figma/entities/style/figma_fill.dart +++ b/lib/input/figma/entities/style/figma_fill.dart @@ -9,6 +9,9 @@ class FigmaFill implements PBFill { @override PBColor color; + @override + int fillType; + FigmaFill(FigmaColor this.color, [this.isEnabled = true]); @override diff --git a/lib/input/sketch/entities/layers/symbol_master.dart b/lib/input/sketch/entities/layers/symbol_master.dart index eca82f68..85cf6a08 100644 --- a/lib/input/sketch/entities/layers/symbol_master.dart +++ b/lib/input/sketch/entities/layers/symbol_master.dart @@ -168,7 +168,7 @@ class SymbolMaster extends AbstractGroupLayer var sharedParameters = []; for (var prop in overrideProperties) { if (!ovrNames.contains(prop.overrideName)) { - var properties = AddMasterSymbolName(prop.overrideName, children); + var properties = AddMasterSymbolOverrideName(prop.overrideName, children); sharedParameters.add(PBSharedParameterProp( properties['name'], properties['type'], diff --git a/lib/input/sketch/entities/style/fill.dart b/lib/input/sketch/entities/style/fill.dart index 063c15ac..3b36654f 100644 --- a/lib/input/sketch/entities/style/fill.dart +++ b/lib/input/sketch/entities/style/fill.dart @@ -12,7 +12,8 @@ class Fill implements PBFill { final String classField; @override bool isEnabled; - final int fillType; + @override + int fillType; @override PBColor color; final ContextSettings contextSettings; diff --git a/lib/input/sketch/entities/style/shared_style.dart b/lib/input/sketch/entities/style/shared_style.dart index 78fd7ac2..203c5cd8 100644 --- a/lib/input/sketch/entities/style/shared_style.dart +++ b/lib/input/sketch/entities/style/shared_style.dart @@ -27,40 +27,92 @@ class SharedStyle with PBColorMixin { this.style, }) { name = name.camelCase; - SharedStyle_UUIDToName[UUID] = name.replaceAll(RegExp(r'[^A-Za-z0-9_]',), ''); + SharedStyle_UUIDToName[UUID] = name.replaceAll( + RegExp( + r'[^A-Za-z0-9_]', + ), + ''); } String generate() { - var buffer = StringBuffer(); if (style != null) { - // TODO: implement SharedStyle.style to flutter style parameters. - if (style.textStyle != null) { - var source = style.textStyle; - var fontDescriptor = source.fontDescriptor as FontDescriptor; - buffer.write('TextStyle $name = TextStyle(\n'); - if (fontDescriptor.fontName != null) { - buffer.write('fontFamily: \'${source.fontDescriptor.fontName}\',\n'); + buffer.write('SK_Style ${name} = SK_Style(\n'); + var bgc = style.backgroundColor; + if (bgc == null) { + buffer.write('null,\t\t// backgroundColor\n'); + } else { + buffer.write( + 'Color.fromARGB(${(bgc.alpha * 255.0).toInt()}, ${(bgc.red * 255.0).toInt()}, ${(bgc.green * 255.0).toInt()}, ${(bgc.blue * 255.0).toInt()}),\n'); + } + + var fills = style.fills; + if (fills == null) { + buffer.write('null,\t\t// List\n'); + } else { + buffer.write('[\n'); + fills.forEach((fill) { + buffer.write('SK_Fill('); + if (fill.color == null) { + buffer.write('null, ${fill.isEnabled})\t\t// fill.color\n'); + } else { + buffer.write( + 'Color.fromARGB(${(fill.color.alpha * 255.0).toInt()}, ${(fill.color.red * 255.0).toInt()}, ${(fill.color.green * 255.0).toInt()}, ${(fill.color.blue * 255.0).toInt()}), ${fill.isEnabled})\n'); + } + }); + buffer.write('],\n'); + } + var borders = style.borders; + if (borders == null) { + buffer.write('null,\t\t// borders\n'); + } else { + buffer.write('[\n'); + borders.forEach((border) { + buffer.write('SK_Border(${border.isEnabled}, ${border.fillType}, '); + if (border.color == null) { + buffer.write('null,\t\t// border.color\n'); + } else { + buffer.write( + 'Color.fromARGB(${(border.color.alpha * 255.0).toInt()}, ${(border.color.red * 255.0).toInt()}, ${(border.color.green * 255.0).toInt()}, ${(border.color.blue * 255.0).toInt()}), ${border.thickness}),\n'); + } + }); + buffer.write('],\n'); + } + var bo = style.borderOptions; + if (bo == null) { + buffer.write('null,,\t\t// borderOptions\n'); + } else { + // TODO if dashPattern is used figure out how to export, using null for now + buffer.write( + 'SK_BorderOptions(${bo.isEnabled}, null, ${bo.lineCapStyle}, ${bo.lineJoinStyle}),\n'); + } + + if (style.textStyle == null) { + buffer.write('null,\t\t// textStyle\n'); + } else { + var ts = style.textStyle; + var fd = ts.fontDescriptor as FontDescriptor; + buffer.write('TextStyle(\n'); + if (fd.fontName != null) { + buffer.write('fontFamily: \'${fd.fontName}\',\n'); } - if (fontDescriptor.fontSize != null) { - buffer.write('fontSize: ${fontDescriptor.fontSize.toString()},\n'); + if (fd.fontSize != null) { + buffer.write('fontSize: ${fd.fontSize.toString()},\n'); } - if (fontDescriptor.fontWeight != null) { - buffer.write( - 'fontWeight: FontWeight.${fontDescriptor.fontWeight - .toString()},\n'); + if (fd.fontWeight != null) { + buffer.write('fontWeight: FontWeight.${fd.fontWeight.toString()},\n'); } - if (fontDescriptor.fontStyle != null) { - buffer.write('fontStyle: FontStyle.${fontDescriptor.fontStyle},\n'); + if (fd.fontStyle != null) { + buffer.write('fontStyle: FontStyle.${fd.fontStyle},\n'); } - if (fontDescriptor.letterSpacing != null) { - buffer.write('letterSpacing: ${fontDescriptor.letterSpacing},\n'); + if (fd.letterSpacing != null) { + buffer.write('letterSpacing: ${fd.letterSpacing},\n'); } - if (source.fontColor != null) { - var color = toHex(source.fontColor); + if (ts.fontColor != null) { + var color = toHex(ts.fontColor); var defColor = findDefaultColor(color); if (defColor == null) { buffer.write('color: Color($color),'); @@ -69,15 +121,15 @@ class SharedStyle with PBColorMixin { } } - buffer.write(');\n'); + buffer.write('),\n'); } + buffer.write('${style.hasShadow});\n'); } return buffer.toString(); - } factory SharedStyle.fromJson(Map json) => _$SharedStyleFromJson(json); - Map toJson() => _$SharedStyleToJson(this); + Map toJson() => _$SharedStyleToJson(this); } diff --git a/lib/input/sketch/entities/style/style.dart b/lib/input/sketch/entities/style/style.dart index 581d3025..89d7e248 100644 --- a/lib/input/sketch/entities/style/style.dart +++ b/lib/input/sketch/entities/style/style.dart @@ -12,8 +12,6 @@ import 'package:parabeac_core/input/sketch/entities/style/context_settings.dart' import 'package:parabeac_core/input/sketch/entities/style/fill.dart'; import 'package:parabeac_core/input/sketch/entities/style/text_style.dart'; import 'package:parabeac_core/input/sketch/entities/style/blur.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; part 'style.g.dart'; @JsonSerializable(nullable: true) @@ -53,12 +51,20 @@ class Style implements PBStyle { this.startMarkerType, this.windingRule, TextStyle this.textStyle, + this.backgroundColor, + this.hasShadow, }) { if (shadows != null) { shadows = null; innerShadows = null; hasShadow = true; } + // TODO: add rectangle fill types, for now just copy the fill[0] to the background color + if (fills != null && fills.isNotEmpty) { + if (fills[0].isEnabled && (fills[0].fillType == 0)) { + backgroundColor = fills[0].color; + } + } } factory Style.fromJson(Map json) => _$StyleFromJson(json); diff --git a/lib/input/sketch/helper/sketch_project.dart b/lib/input/sketch/helper/sketch_project.dart index d13ded3a..4db195ce 100644 --- a/lib/input/sketch/helper/sketch_project.dart +++ b/lib/input/sketch/helper/sketch_project.dart @@ -26,6 +26,9 @@ class SketchProject extends DesignProject { final InputDesignService _ids; Archive _originalArchive; final Map _pagesAndArtboards; + // Map to prevent name collisions + Map layerNames = {}; + SketchProject(this._ids, this._pagesAndArtboards, this.projectName) { id = _ids.documentFile['do_objectID']; _originalArchive = _ids.archive; @@ -46,7 +49,7 @@ class SketchProject extends DesignProject { var LayerStyles = doc.layerStyles['objects'] ?? []; for (var sharedStyle in LayerStyles) { var layerStyle = SharedStyle.fromJson(sharedStyle); - layerStyle.name = PBInputFormatter.formatVariable(layerStyle.name); + layerStyle.name = GetUniqueLayerName(layerStyle.name.camelCase); sharedStyles.add(layerStyle); } } @@ -56,8 +59,7 @@ class SketchProject extends DesignProject { for (var sharedStyle in LayerTextStyles) { var layerTextStyle = SharedStyle.fromJson(sharedStyle); - layerTextStyle.name = - PBInputFormatter.formatVariable(layerTextStyle.name.camelCase); + layerTextStyle.name = GetUniqueLayerName(layerTextStyle.name.camelCase); sharedStyles.add(layerTextStyle); } } @@ -131,4 +133,18 @@ class SketchProject extends DesignProject { } return sketchPages; } + + String GetUniqueLayerName(String layerStyleName) { + var name = PBInputFormatter.formatVariable(layerStyleName); + var count = 0; + if (layerNames.containsKey(name)) { + count = layerNames[name] + 1; + name += count.toString(); + } + + layerNames[name] = count; + + return name; + } + } diff --git a/lib/input/sketch/helper/symbol_node_mixin.dart b/lib/input/sketch/helper/symbol_node_mixin.dart index 0b341919..42b45f5b 100644 --- a/lib/input/sketch/helper/symbol_node_mixin.dart +++ b/lib/input/sketch/helper/symbol_node_mixin.dart @@ -1,4 +1,5 @@ import 'dart:core'; +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; @@ -43,26 +44,28 @@ mixin SymbolNodeMixin { return null; } - Map AddMasterSymbolName(String overrideName, List children) { + Map AddMasterSymbolOverrideName(String overrideName, List children) { var varName; var parmInfo = extractParameter(overrideName); var uuid = parmInfo['uuid']; - var nodeName = FindName(uuid, children, parmInfo['type']) ?? 'var'; - // only increase count, make new varName if unique UUID - if (!SN_UUIDtoVarName.containsKey(overrideName)) { - var count = varNameCount[nodeName] ?? 0; - varName = nodeName; - varNameCount[nodeName] = count + 1; - // first one doesn't have appended number - if (count > 0) { - varName += count.toString(); + var nodeName = FindName(uuid, children, parmInfo['type']); + // only add names of our direct descendants + if (nodeName != null) { + // only increase count, make new varName if unique UUID + if (!SN_UUIDtoVarName.containsKey(overrideName)) { + var count = varNameCount[nodeName] ?? 0; + varName = nodeName; + varNameCount[nodeName] = count + 1; + // first one doesn't have appended number + if (count > 0) { + varName += count.toString(); + } + SN_UUIDtoVarName[overrideName] = varName; + } else { + varName = SN_UUIDtoVarName[overrideName]; } - SN_UUIDtoVarName[overrideName] = varName; - } else { - varName = SN_UUIDtoVarName[overrideName]; } - return {'name': varName, 'type': parmInfo['type'], 'uuid': uuid}; } @@ -89,7 +92,7 @@ mixin SymbolNodeMixin { case 'textStyle': type = TextStyle; break; - case 'style': + case 'layerStyle': type = Style; break; default: diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index ee2b67d9..03edeae2 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -45,13 +45,19 @@ class InheritedContainer extends PBVisualIntermediateNode 'height': originalRef.boundaryRectangle.height, }; + // have to save this in case it is overridden + auxiliaryData.style = originalRef.style; + if (originalRef.style != null && originalRef.style.fills.isNotEmpty) { for (var fill in originalRef.style.fills) { if (fill.isEnabled) { auxiliaryData.color = toHex(fill.color); + // use the first one found. + break; } } } + auxiliaryData.alignment = alignX != null && alignY != null ? {'alignX': alignX, 'alignY': alignY} : null; diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 285339dd..10c6963d 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_instancesym_gen.dart'; +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -36,7 +37,9 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; - List overrideValues; + List overrideValues; + // quick lookup based on UUID_type + Map overrideValuesMap = {}; PBSharedInstanceIntermediateNode( this.originalRef, @@ -62,7 +65,10 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode generator = PBSymbolInstanceGenerator(); overrideValues = sharedParamValues - .map((v) => PBSymbolInstanceOverridableValue(v.UUID, v.value, v.type)) + .map((v) { + var symOvrValue = PBSymbolInstanceOverridableValue(v.UUID, v.value, v.type); + overrideValuesMap[v.overrideName] = symOvrValue; + return symOvrValue; }) .toList() ..removeWhere((v) => v == null || v.value == null); } @@ -96,7 +102,7 @@ class PBSharedParameterValue { final String _overrideName; String get overrideName => _overrideName; - String get name => SN_UUIDtoVarName[_overrideName]; + String get name => SN_UUIDtoVarName[PBInputFormatter.findLastOf(_overrideName, '/')]; PBSharedParameterValue( this._type, diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index e66cd46f..40bd6358 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -1,7 +1,9 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_mastersym_gen.dart'; +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -27,6 +29,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode final String SYMBOL_ID; List parametersDefinition; + Map parametersDefsMap = {}; ///The children that makes the UI of the [PBSharedMasterNode]. The children are going to be wrapped ///using a [TempGroupLayoutNode] as the root Node. @@ -43,7 +46,6 @@ class PBSharedMasterNode extends PBVisualIntermediateNode ///The properties that could be be overridable on a [PBSharedMasterNode] List overridableProperties; - String friendlyName; PBSharedMasterNode( @@ -85,21 +87,25 @@ class PBSharedMasterNode extends PBVisualIntermediateNode Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y); parametersDefinition = overridableProperties - .map((p) => PBSymbolMasterParameter( + .map((p) { + var PBSymMasterP = PBSymbolMasterParameter( p._friendlyName, p.type, p.UUID, p.canOverride, p.propertyName, - /* Removed Parameter Defintion as it was accepting JSON?*/ - null, + /* Removed Parameter Definition as it was accepting JSON?*/ + null, // TODO: @Eddie currentContext.screenTopLeftCorner.x, currentContext.screenTopLeftCorner.y, currentContext.screenBottomRightCorner.x, currentContext.screenBottomRightCorner.y, - context: currentContext)) + context: currentContext); + parametersDefsMap[p.propertyName] = PBSymMasterP; + return PBSymMasterP; }) .toList() ..removeWhere((p) => p == null || p.parameterDefinition == null); + } @override @@ -130,7 +136,7 @@ class PBSharedParameterProp { dynamic get initialValue => _initialValue; final String _friendlyName; - String get friendlyName => _friendlyName; + String get friendlyName => _friendlyName ?? SN_UUIDtoVarName[PBInputFormatter.findLastOf(propertyName, '/')] ?? 'noname'; PBSharedParameterProp(this._friendlyName, this._type, this.value, this._canOverride, this._propertyName, this._UUID, this._initialValue); diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 4b4c4302..e289e15c 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; @@ -11,6 +12,7 @@ class PBContext { PBIntermediateTree tree; PBProject project; SizingValueContext sizingContext = SizingValueContext.PointValue; + PBSharedMasterNode masterNode; ///TODO: This is going to change to the [GenerationConfiguration]. PBGenerationManager generationManager; diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index 11905d75..e942eb57 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -47,7 +48,7 @@ class PBSharedInterAggregationService { void gatherSharedParameters( PBSharedMasterNode sharedMasterNode, PBIntermediateNode rootChildNode) { for (var prop in sharedMasterNode.overridableProperties) { - var targetUUID = _findLastOf(prop?.UUID, '/'); + var targetUUID = PBInputFormatter.findLastOf(prop?.UUID, '/'); prop.value = PBIntermediateNodeSearcherService.searchNodeByUUID( rootChildNode, targetUUID); if (prop.value == null) { @@ -115,12 +116,4 @@ class PBSharedInterAggregationService { PBSharedMasterNode _searchMasterNode(String masterUUID) => _symbolStorage.getSharedMasterNodeBySymbolID(masterUUID); - /// Method that splits `target` according to `delimeter` - /// and returns the last entry in the list. - String _findLastOf(String target, String delimeter) { - if (target == null || delimeter == null) { - return ''; - } - return target.split(delimeter).last; - } } diff --git a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart index ad1c6abe..3673a5c7 100644 --- a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart +++ b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/directed_state_graph.dart'; class IntermediateAuxiliaryData { @@ -12,6 +13,9 @@ class IntermediateAuxiliaryData { /// The background color of the element. String color; + /// the style of the element (which can be overridden) + Style style; + IntermediateAuxiliaryData({ this.stateGraph, this.alignment, diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart index c30de146..a596a56a 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart @@ -1,4 +1,6 @@ import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; +import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; class PBSymbolInstanceOverridableValue { @@ -7,6 +9,8 @@ class PBSymbolInstanceOverridableValue { final String UUID; final dynamic value; + String get friendlyName => SN_UUIDtoVarName[PBInputFormatter.findLastOf(UUID, '/')] ?? 'noname'; + PBSymbolInstanceOverridableValue(this.UUID, this.value, this.type); static String _typeToJson(type) { diff --git a/lib/main.dart b/lib/main.dart index 2c416afe..9a075a35 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -59,8 +59,8 @@ void main(List args) async { help: 'Displays this help information.', abbr: 'h', negatable: false) ..addFlag('export-pbdl', help: 'This flag outputs Parabeac Design Logic (PBDL) in JSON format.') - ..addFlag('include-styles', - help: 'If this flag is set, it will output styles document'); + ..addFlag('exclude-styles', + help: 'If this flag is set, it will exclude output styles document'); //error handler using logger package void handleError(String msg) { @@ -95,7 +95,7 @@ ${parser.usage} MainInfo().figmaProjectID = argResults['fig']; var designType = 'sketch'; - MainInfo().exportStyles = argResults['include-styles']; + MainInfo().exportStyles = !argResults['exclude-styles']; var jsonOnly = argResults['export-pbdl']; var configurationPath = argResults['config-path']; diff --git a/test/assets/SymbolTest-simp.sketch b/test/assets/SymbolTest-simp.sketch index 1425c07c46cc7678c963205174ad24540fad6051..5e3cbde60e11292502bc9b9d92eb07db273056af 100644 GIT binary patch literal 26493 zcmeGCgL7q1^frn|6Wg{YwlPU2PA0Z(p4hhSiETR*+qP}{p3nDve^tNt{s*`2-BqV{ zpRRtod#~=j*0Y}8f26@7&_TdJph5n-E?B)%Ip9D*W@JG?5P<)U?Ti36CbrHDmQHrI zm)aUm>%URIeliG{H98S_WU?MsX1CHUc3%{0Gr>rzE0M!NpjqjBT(5&~@zg`o*$py( z2*I(Yof@_GToJa<@~kTbNTb8ilR2S0u0gN9rDrYW2Ddn?h`Dn3n-XM+kgCG+7|TPbTn)!bQF1Y zV6MsJ1h|{GS4T?z_#oI`nsOKzW6pejM?@E_TGmQ#tY7FN1Po2Cl_?rnXV|X@1h}O2^baQ%;-rV=0IA@z7Lr0#SUVcsC zV`U*YQ=W=3(@-;dI^ziTDx0xhf86C3^WLNZe|a%~l#F#+K8nEKFPAYU{I_RHT)hCP zT%gzul=##S$}pv^KN})hISCKwzgTc(8wtgRVD_Zkj5X}3(@$!X=imlCpdA#pRQZ2! z6RgQ%6I8Zv5vSCOZdgQF=R-QsMWJHCQT{?QV6ZFKphCIxvyIaFNjeWHMg@vN7d>K- zE2gg+NTER}i!|hE-V?jT&m0FJcV{xN09}i{3YEB(vRq-I;JW9-Ta5Rfl_3!*)F&C)I)H64 zL4HRb-dm7N8zz9wMn6Q<-X~8u8w~&z+DC9J>4jyB#i@_54B{UOfgQqN*7M`*Vk$`l z!Tdi_1{_FRx2!6*D zNu8EZM6O^WqX&M5Hi)>-6TZvrBnsoN3~_uI;8uw9h@3$nCqP*qd`teW?c+YOgx?&tR zf9^f!<7{u(b#{0Q=H@i(q!4B9-_GyD#IiMY(wsTYxwyrZmztV<)(UWHYgB-W)Pe`o zjK>@NQT1PPOz5YV(=f{mItxT&Z+EtJt2V7w8TCFYeZB=wV9VphrJ0`3AG(v2y}Roe$Wxgp*CiEiK_$(g zu9JL` zuUwFVl$rMTziB`6pnOR?yD$5bA z6tN7bYb_g+_Px&OWN`OBPMplT7h|r@=$H&rTXa5_T!i=9-78L;@ZD~vL&7>o>wG06 zqX9!qeAQ9gUg&0vz?~P}1V7enZf3>`=&OX)QctI?#N|#edwkI+KcPm5r zn~BmL(oZ%|kp%x{9Xkd!#6v+e*9{LVhv^clG0;H^ zDVcf~K0b+))+S=)*I1BYoG5E?w3IQ^RbOi^N(;;_m{UaQ4J_Rhbz$;^MT8Q3f^Mu9 zm-kq!2G+i50)z}q1mEGD5F|7TL^-=~@M0W<`ykXlVbnWLJTEucYnb@ZZzfwhw7Gas z(L$1me!E)np-;>Z4EH|XlJ%)p5HZriF3Fu=ISy}H^O-Lsj$oXoG!@HQnOp8MmflOAICraS_ zDY3jnPv}CoE}Jn~oSPzr%n-*M5BkL&Xw8N~gCVx3OP+seZeJvr{&VtZ(b2US;+iqj zvDx}D^ZA~mHv6gg_mfTPVq+&ZmW_<2pxyvtoZVO~>%g z&FJF{(fUjNRmt!kyp`4gUX z$RlWs{>O+aN`jnESjOxx|9K0-I%vRQEWrIZ;x_c$qdP;EXTXL`ohi+2Agn(ON-Bd@bYW(NNtBE7E|Y-7|=;k6Wlgbrm@IU>w(A_!{)PVG$#F%6} zXN+h!x49+hcy6yRFCjLdu8CM|Y@5*4ozf&cANOF#!}2VkE?#`B{Pg+9{R0iFM9*o_-t*%DEG+ggyc%2EOo)xl`0d!nJ2L!h%?s9{f+MFz1Zw^TFzVGB4O)P)9Mi6!wRo1+^(rDtI` z=aIP#KCj$84PGCb4;}5DJne^vmzU+EDd~b`O_#PRKjuHr?Ixth!PG`9&_Mp)K{@0j zLGO&~PnCvA#mdE98n-*N7958Lq!P zOhrqE8{`T)?J?;ak>jt1@f!++od^$z4kq$)UTz>cd^!gjDH*${jpPxm|( zEJTl92u!-nqCd+#HJWvOG5+~K2sU~9oo)}1SzAVefG`3Hw!MLwi4!BM2!}AMC>tmJ zFD`CTdNvjoG5TL(BBJ!H94y>SY^*HoVw_z6i-PNDIjwWmfBmH4$0OWebSDEbq&k-2 zP^xo%+MQ61h&PYKOIKD{AkRtqez%BQm~>%@Fyd|wb+;!6fxs2o?_WNFd~^rW@Nvw@ z+3{IE-f4010?Ef}kMC`-jn2Eckt~_CV^|FvzP+U4k>V*b%Cf#Jg?L&7q^_EBjhtk= zBlm1}F_joyQb#sg%)c*5@^Tg15g+@V<(aeN4c5&g>scDixyOmQ740t#w3*f}tk*4_ zwh^~-Q;dr*A_A*YFIDR3*JiILCQ6JX1}Qp6kBo!)l7f>Bj$k%=QzU3a(PI~20#TT$ zSl1P+h6@y(XAs)_I>(WF)A@X^DsARxmDIxeqa3H_V`t^39WZ*B^OoG1D?HNzol}@Z z8|Z}E(yiJDj}>>7xLqH7xN2C#8XDTht6n~x=0oPUBz8keY`OH)`((>fjYK}dk``0} zP{Jm?m@oxs1L23%3PEIc#tA12b)q-3i;J_=-{|6RlYC<>Vae50Zk$lRYw)L2n11&R z2z#>olYT$v`amzo*1WrFVqu-@0@#DgyGJsfn9ZLnZN=Rxx^R=AGjM8t-!HdE!~!s$ z*=6tdyw(~oz33<>8$Tb)K0RT4|86-bLt=k$HP=)~a)QoV?>5gZFVbg>uT~@Li~*Wd z+3LvEBe3HU9mvqXi{c4l=>oguk*<-A7bhr>dCN9!hVamlK3E{}Q9 zjln=ax!{QTo80&`SGpQoqUApon?R0r%pN=F{(Ahg$0~p+&bTv;ks`Jj<)qMtg zn46KN5+@Y;yYxY5Mopu6``tz4dAwx8d2LCg2kw4s|(OylTrlr2-4=sjuh zXnau$W0**;1kl8nTMc=O-#uwyqB3qOp0!L>!@!Utd*M`i{{g==BiJ0F`v}Lh)Lk`5 zZ|z?${@7YQ!4=PSJ66CZ%e*IrRv2jHhqT0c6$Ho;@QEt6ifSG&E*snSy?fPY&SDQ8 zKC2!ofyq*?j-MaF%aGUw(=`off`06@{97zrwlUsp&73PXIQNEb_ZRnp%Pa zube=GxYQ%<%LDXDkk3c=p|t8D*IO!bx`{7%=AM$bAe%&evFLpm)FV%r6^5v%V4$4B zM)Bhjy-;{D18Dyh&fyyQ!x)DL-fA2QAu`Rw%ftKu2@n>35|ym3jk-xaHp!%@olV1$3R*}g zZ#|*3fka35_{D@5{ia}?_UyQA9uOGQ?Dq*Wi&r!+`HDR~a%o{gZ zvPvY@bn#-C>0t9RJpLB@v79!m7=o+m)3Mh1QaATe`V&<(aZ?_Uxk7__+LNui{$uZ} z$K76x_iaGEQQk6mjjxr}Vw)EK_2=%0PB7Us>Hn{^O@sgSbN5Ck_?$4x(i@ZJMGAH_ z24^OKWts}5_-jNfz(ezs_4}n+GX-sVtaHU8|0ia2G+t5u(KWo#Kv$+}w>%i!6mhXE zY>J#^{NMtqS>>bL7+cYWsx*|~SmO7U@@eDwX%3Xs1L*XZmXSW@WbDeT*KNz~x&2RR-ocYoxNXZ=RY--CoX-FkYuI;sbuk+F$ONn?9Et1h5Y#|(! zlJg6L?YdtCw=zEEN{!ucR~Rr4;iyn*<+j6(osJ09F-C6!p8S{BA51P=sjb9WRq z5zh~?lR9NK!!f>!1{XS8DNp*Jcbz!SwSw7#(f9GGRbh`7U39~E&J(7C?(Vbo#;`UU z7s-+L-kvSp!5xIr`q5%2r0-^;mQl=q^--bmS-($Q6OG9bW4x!TB^&0yq9tgx{|odRdZ1N9eqKq~8``?VX(r znw9%C_zOhy?C^#QDdgC#qE-g_+nkf4@~v!Hb9^Dox0A73MVBKQyz9JcURAJsE-;s6 zE7nNWnx!QAPMWDS51mL9md6UJDZr?rqlL+Ay%^#{u~v|^w4SZXZvEA3tA6_gv^}vb zj;7EfHgm7DEE;IG_6Pz@Dz z)SPRf(6`Eg-|?t~@h&Db`AHz7!(C&foGRT7RcdeBjpgnWBUWGYws&I)CY4asDgI;- z_5|MzgPMr{OQQ}K!y*Q~G!WAF%)bITJ^L(M8eb*@BZX##lA1Io(IJ28nB!Rv@J%N|;&?e@WaVX!{9Y&&$L%pX|v^~HMn4}dK zSk$4ADgl$K#oWkmuZ)}jY3tkAqs?_)mkh7)TUef^nL6Cyg0hgq;Fn|iiyc#u;yyM& zlq|dntSJ@IzZ%b2mhZIq->C9-EKM-5|6Z@25ij;_%8tvHob7+d{&Qb8G?)8u|J*Wj z8O=04lM0xwCTBJrca_8-O4j}`kYiqEbWu14dZ`@@4b?nl_u-xO1#os((#Kj+5^?S9 zhcx5!?F9zZ^%)I7F$H4hjaOt^E!;A zGxpgJVW+l+=LW=z!J{MH8U0oWqQ2|_8hr)Ll25vm=pR4i{L^WO=Y!|6rF6$Gjail! z8Xb#YWtb7zdwMcxxadDzWPuZ*oUL(_?p;}^?N_kcW7HdAceuvv;}2qg06FuVdT3fC z3Sk)vv@(1cxXTo+8FnK09HK-A)?77nQOhI`%sW~^2ZVVIeAMNeYF5kP^s*3u%I={H zWp>6#YdXj5S*Qfc>YiIOQ>Tso5(ANnCe<%p6MH~|NkXYWffhA)CNJ2w=7ex^E0x1PKU7q@uMlG=oFgz5H#8sIT8k zi~vZsCkGZq%>?okjOSr9h%emIbC2Gd*rZ6$)vqF+UnxD=oc`}=rb zQQ}eD=ZcJp#EbUw2CXGb5Y_O{=pml4{cG4)H2=HEA6&DkM66p>ro#2*44<~wH=q}B zLpUlV0Xq~)$%FGh?XJA!{Rx!@(G#WYr>F~zy*WSXy3VH+qhh2hBQ zp2GVUoKPX}ExFQgw;nk=&+Xinw{NO@%pR+IFvbw4UOZtxpTY|y&rlD-WKouH&FZpb z_hKQq@x72G&-Zy6IemzHe7Ve?b*r`~qY0S!Vw9rQ&-_1VrjZv+k(ENo<>00fygh6$ zmT(3kk)D>Lqs%L60(yc^vX%noz@dDpqBJP>*bys*QnP<+mY};!HL7GO&Gh$K0N;OC z2hEz&Ay6O6hse4Ocqee^vv`WxBZ??u8xXNJN5T?)acQZX8>Ce=z$wK zS`zwRSf|=r;@kwb-*k{>{9u-0`!!37=wUyKWEzV`{c6GgZ8^<6=ZJdOQGd>z7FvP zZJ8`*4xP3RstTn}a5cxb+rifVy7{SFtPmhQm@XtIZbpm@YRpxu2xAEWJ0v@UbbA!y z&GpZpVg6$NA+}q_DVD`H``1=U(7XC7R7S6N#@A;Fk*APXEXx%>+4u1|(|bYu+1WSf z|CtM3^E=F0L4kn868-<@f}&zfqU>C(Z1f_`TwL^Q+`qZ#xqtoUrWfJlU}5555#?a! zWdC2ep!&MwMk~rE21f3WP;w!^1w7D%Iu6x~JM-+&fuaBj^AMC!{rJ2hjl~a7T=L_8 z@w6ItOAgu}%nGhtD5^e@z z5=p_-dm2Fy1>Mr0K^}B|k}aBQQcKr(i&9EwYi&YXZAva0ucZ-IpJmEO(YDb}4pbF# z2>dFmY~^kh>vvc>cpCiI?}eI5M-4fyJUwcI3jHPZKka@VYNs`ahDg~ezgJ(#yseD1 zgREyl@@zVlq*%S|(s7(?>F88UaT%>2hB>qdRkYuw*6YIRxE3dyAf(Xt5zacp)|7wlkVV}!XpZn+mgH`bkbAw7Tn1d_%=7E-lIYU7YJY;@j` zgA)~>6nvpdR0vA`C>ma``imoyx%F!0CXwM>XMAgG;IFn?`wzKHRW+ym`#qaIiXm zR#@H@Raz}FsMgOQDM`D&G;As`_w?vCwd+;82y6fAfpkf^nuMQP+;i-@ihks_N^TG2 ze>g7qyKVu#wis&)I%?Zw9cd;S!X)T)7}2F%9Jf~lJtsV{Z#IKdVs)CRG>2pF7ZG95W`)Eq+kAVikyc@pCE6imye0h zLnmuJAwk)&Cyhtauu=hn`lI1G?WupZpCMros7FE<|GZ72FCev^8)A}CdJ&;aA5&A} zljZEJnEkp5npgYbtumumkmu>3v4U}S7=}!4GVxXDodTdEPC~&aM)81{x}@`W%A^Xr z6Wx(n$>f02)}xf<(Uli5(!xATtn>inS2qY8Gd7Tepnd#HoRd|TJsZP?MQ2?dapv(FXn?e_+T28k%IWpA6}Go z-v}UR(}Diver&(vRE|&wjD%526mVzaC@o}cg;mt!h~kf{1X`z-LQMo#A@do48A2OH5=hm{EBU~{$AIkgr<3PQiI1WWx@Ec)+vt?(_De~XZo=KueMrBdC z#wbC!I0xfyF<(MelSaernrFxSLMv_RBksrtRufLZ`iLrGxEo=4B7;>!zzOA<+*5K} zv+6~f_W|4=2X1Y=uK9;IwoZ!H^rOzQnzlQKU)Mh-x?B|yjJ%&tfy`g$_7rNnZ+vh~W!bBsq`o=`xLZ2i80 z3Q5sB#6M`Nv}FEAct!GuqNS(d4zsQ}{npdH{gXrb_PTggJ2p!L+SRGL;AvOo{BRv# zMs$0nSke35aq*lZ<7YF^9Fkqr;pl-7I7T>&Wcs@Kn2VEW;a$Jf^4UaA(%Ti{!Z(5S zk5)R4Kf%pKl~l7ih#pd_N%gVKLkjkd8D8uMeY~A~4f?zo!j?%F9!MWg3+H;mA|p(I zbi5rV()ejGndiQ(SS8ThwETQ2PGLJh9x)KP()GMSTp?s_Mhd^}5XXZK ziiUY1MlQN~iKVz0O|ydtYQf0g8&MN=@x$M3XJ#4$U*;@xZ z!KU8mFnM;$K-^w_KcA_3LHj*zgT=4;6ZLAmTA2=Y86uf)_*a=j;0>`^mMI^~tfBMVfI?7V-CS0)R!2|IqedD&;7y;4@3bWK! zbtGIvP-$ghD~8?}QccP-0lt{%4Vl$oUq^8?dTui7Svd9~mo;sq{@c4NC(Y{+#{Jhj zcWhTXS!T%8O;et%VxvqqoRQQW& zyzR8^XXs{<`5=uLYO=#2IM*SC{ZE>MG)Q8S0xl;x!(DmmSN#1MUk|56J$R(aFvOoh z(Y-^GP+Okx+O%M_>X5&WVjMCLmu6WZmaQY*v9JQBypc8afw>Tv>nL~&CcMiE8lz;~ zE{^{e$99Y_TrSPuXbAC25C-D}NkmI^>^nLws#a_Uly!*U9DdD<2Ipp+gkS(JAR-57%S3=6# zoh$_*r%WMuBPJ<0drJB`N6P*Oz7u=4gkR}vf5q|s4Zzxj3Q%5%JM$xM3jFIRwmoLB z`1fg~Hv!R1apg$1@jkdzQr z1OWk+0|5aWfQAItn8mG10dJsAisHXOs;BTzfj$L9QdC&k4fJvo#!DNp_(6ibUr)N!My>4{R$y{x;^}KuLj&izYdP>Leouv^P2!Vh?AfL1d zS@e_`|AIgk0`aF7vcLQNUv)h?F;@eGkt49yZ|8vD4+IR_m`2Fn6lUlEn%EDdZ`AWY z?1-Y@&ID@IC<+h~koXL2L>yNH(w9zwok#|RKu}!+8wn9hg9fllGf|2IA<%ML;J^-q zQotb0QuJkFfDq)YPN@IJruzXsMc0>x4}=hNxg!Bb0n>m*&e8~A<_7i)oEYK%H?jZc zS&aHwj>&4tI-T9K`Pp_(5aRB){@B4Ni^GYVhHWM zC7(~hW-5fUrGB!MDfD@B)Iu#gnD<(0QPHO5DiC?ciaH9qO9pgh0>TLq)J8kcD zMg)a`6!F`^hgUfY2LY@8v7tvW3V4KUaN-Z-z6Z;6mGq})jO0B5gE-DZJN5Mrs0AWW6%4$g@XCgY%?}J*tNV z{?%z6uro1Uze1-xJ$5?RcHm5Nx*=D7Mi_ra^DHU0C___YoiulM$N{GSQuW}hCSfKX z=v;$KRVD43kWzd-GA8z@C~yW#gZDa&oR|G$1`d-s75Mrvu)~??ZnDp7WfHB^rf%RtN84N9Ei5LfEYQSm84v6~$$4 z!c_76+dE6~PkYdShF-Xp?ZNBQ^2DjyVs4kUB1PV>n6K`r(>Ibo%+~(a^_$Cu&WpoE zp09sD-F_sZw}bR)oM2oW-?=ipl|>Qy_AErT)#TRb*IPqKjjN6Xx#p7SOl~LSB(EFa zD;CoW0Y?CdOt~a=ZSqndlNy%TOsZ(`K7}k{q#6BA#BbSj(OPxgjn&S0(?r2HDG0Uak+;j`vaJ}Aiyd4yb z???JRh?BT#m=?I}*#1um?~h}_!!GC@5r*DV2@&0ZJ{`ZSW~A|v z5Gcnv2@Q>OZMVMI!m=`jZjXQA^==MES=Wnd-->c?YvGOy3b_epIqs@gUDw^MkSj}T zv_I9VBIZx5#AEPj=;?vq;?ANBM-%X>Qp#X6+I7FCRI1nI+u>A{mlxL8E2c2$tUYUb z=hZBq^6>JC9hVrqUi%7?)pXvKH-Ihh*) zqmcK$)2+Vf3zL5*N=$92yq@Ig+IVv0D{JguEd6Mw6Dy`t=@|?GDGjA>d%3k0kMk-c zx6iL<-xIh=Hbs|BKAL&-+QoLq;D4*KI&amhYFlqJjcS$@iFAOyat2mzco2U~YWRhC^nS^W3s=$7S(& zwr`tG4AS)H?(_19EaxV2$>%~zOw>M=YzDS3A+M>7*VhnUb!-P}b@!W;`?SmYBYmg< z*Tanb2!TO&&&Q$49PehXal<5smQ{xT#~;ll+J38CI3j~hC*p?PCU-g^`y&Sj$WC+q zLq*a>MFFoVKeHm%v~HX0*}YUf_d|mF`KDgZEjN+o)uT-Z*_-K>ElSU;wvvU##X$=s zplt8{Fgv`5yE7~9tLeObkZzVuPxN*pez-6%m&*UVBGT=Af%Se=LGq^e{i)~J7mPJ} z?fd-ReVh9-K;k$**)nok;@e=SeHM7_`|VjjN|`wl5lBA% zBKiDD37!P#bi<%gk~iSqJlBs6c40~5++?K*3&7UKvJzD!6quaB^l4x+ti)IBz8>qv zsTkxQ8iW#1A_+XyHn!BfwjPm$;?pfIF5cBp^{WK_%M*UN+5TpLB5=;@d|R_}5X>i( znG;@?14OetO1zN8^3jf`&__;FeOGmCD-M_7rOIrhF&Gu;LMxljBF5135rJ*_w$YCy zi24+KMGJ>X7bi~SNe5YMt9w2Tj>4x~!~v)QyhsSMzW=%Ur;M}5q zd<5JL*2*g#|Lq^M*FR0N%i`F%;W@v+ar{D>N>q~L=Kh$aPF`&|9#N9#CvXA3z+Rs< z`Fv`bPMVi{57BmbHF3zQF4BGeu1+<}^D zohA%Oxz8KDd3~rqObx1dfu9o}iu|GnCJE5SKY={^=g`Z-?%!1(=i& z$5jEzb`|zKnV--skSU3MV`5_qk!GK~fLU$_p?Rb^I7;zBisgdw7dnwk_y zdfeDKPTKj>mw0^|>K1)9zoU1HHEMgxp zakT83R63z=MRw;LM{DJ=z2d#jGfT!>re0h+k4zjZ;1EV-IkQn~{CG7V${xC&r#CG~WV zHYT3YvpXw!&dYLMdiu;GYv#UxU>)`bBF0$x=OU_k$rHr9-=+SmV)j{oE)pz36y&<@ zZ0)&^vZrbF7VP%zbl&VHdN1{Qe5o0kmlveB>v~MVci!>8rSMpfp>JLx-H0va#GX!P zCfmZkYRG->ylD9b-TnH-ImRh3DC_)f$#T)WUcI}7BYUfgU(=b@tvA}Z>ZP~X-j<}? znLR0;*6au5{9v@IOOcwSimH!(jck|kkJ9s9LN(-tnZ22I%}0a+W%H-NXQ;BB%3^=! zdg~{uj@~VH9q_sv^&MT(vRiaj;_$vSN!4KpCAux^t{MOLBQ{a^*|+|LWd?H5 zXms7g4S;Ny!P2%@_{iCaXSMJx=y_I_u)42SRBSR;8~QyRiFNc}CY)+Ay7?8q5xJUsd}N#5(6r3>fe(yD8Dw}|c| z2f0bN?48=4p39@GtSn`wcI}_qv+=szTIM~lo0}BtbwG9-FzQkCb`UUz+uhEn)brq% zxYbGj_*Qw|fgx_0xyom2gV?A2Ww@fOH=k;)JKgxo*efvgQ8Vk8Qd@XtN5VCoqEe+L zbr|NlwL`a_evZ4#v2IP48bWr?x#{K9S<-e@@FCiI92c@E@8jXn+%Un_wKXsCTyo|! z-;c=4Ca~rE{b{^60CTr)RUKY4|K7Om{mkz;fD$^KYX{TPKO4Lk3&P`eyKm1^LpeDG#Hc^_JkNUjZNyELh9IFOE+m^ zGe4kLb~2k+E#~_S#_^0(4#vP;LOXH(#^Wg6?63q&57jQ2dFQvHXH{Xgn%<`k$iDO^8b~i_B6-e6CGNQD1sARk#~X zYkg-T3`gTttd4(2_(F8^3Z-d>vWX+NJLSegr;~Qc^hQ=$PA8}7AiId-t1oRQ@{YZy zvbdd$bl1L@ACkrc)Or~C`|S{+4k9?&-jP&SlpO6#YtNUjix|t?l*Wd#XyJ4P^i&yq z?RxZvgYYme_yUboJ7)ia`A19K58lSC;ZQK z-!-OV&R_(WX#Gd8hjZPQIZ3hnlK-kMa3X|&K_`H;#HFtBOrb38g~lSwJ8#1Ki^W1u zfdA2g@L4IZqe2tcjF8GHr;XM+NAKsM(G=|8QM38?QMH>y2j#9E=`?RBDOyvh!vT@P zibMVM=Q(agjV6h5Ji?T-cJV^PmkVT&uH5%2pQ&!WzXq#ool0C?R*bU+#}q2Q$q|z8 z!A=}luUA}Mo}nOpuZRhxI4J+>8jmo`D!WD6*Ig5fWQpP_8WHCqeTo zB$$@ACv%X~2!1{q((o&?Tv*T`5z&^Wy?i34!7YFP$^ig_Z9Bb$@G9V zHQX)^1N>Z3uAP~D3~fqMb)12TK~;TYQ*Nouk&fTagYK^NJC>XdEe(>|<18a21hT}> zURp6t%-^Iy$toQfrzbf00)c_N5QCU&zMcv7KcNgr{!N>AasE@o{)^cu!SVm8V5UG} ztN~&AKdH+Ch-;*a0ty)rEWqVSw{e36;v|66D>gA8|4&%c00t%Ne%AkRnm`;q92rn{ z^Pd1x1XH{mVIXb}sFqo1U<0)bXk(!6!Mc6}{~u1(Z%1bQpTvJdHvorT4Ke#qZEFPL z{@*y|vH2JiV_mqUHQ&|IKhDCOn9B{okya0IN~KbS_u6n zqA!7^T8IVxM1%2U;-d*ilp2`7l1O}k`{JWYR=XaBtlVTH?N(7!leRs)r00)xzh=1Y z9`g$_HH>gMz!rOx_z(kwh4LeQp(;Ww8qR3a`(aLv5qgTR+RR4%eMXOzU~PTfWOnbz z-0W)nu=GT}O_bl4u(gE-NmUg+OSwzqLa6L>Mn=3M$}i`uk2Vs%Rp)K&!lYSv@bPDaIcL=#?+Z`j z$*hWsJ&e7wze+OQ-r!2^XA&##EwFJAJ>Zc_R8EP)l7Fg=MWh_wLfm+14#|uwYVp$M zOy)s3%poxEoDGiz1mFLBm!vi?? zENFJ~;t-`9xMFJ>3!jyXhH68~^(J@uddJ43aM;^9gWl(Bm=X3x14(eC`b**|gY{M- z>=7-hAun?wkM599;4r6Rp*nDX%^X-F(5sE7TL`>CN%qh|ZR!;G>O0RUrC{Fy70iiP zo`Is$N_0sSS5C4x6yqN5V3s}e+9o=B0}^EG>M^`)aD3eAR<1{wPiU(fH3L5J^DPA@8dY)wl{(Z zep`B53CIv0JW6NBxl}S~-cS5)%t0_3l5&3mFYsPC)STN` zQ42I~NAR{oFwnuGobxjsK>~Vx!87F4eCJ2a@gXl-iREIBbT*T!Ejn#B->O{J&zXe< z>O-UPeagQ+w34B(a7Tl(00elQ#6{s{H=sbdZ`yp-Ki^azf^3RgU1kGt1%wLa5a<oGNt@`s@xe-*HJo4VpE(Cgh_Qnak;TDrUFZS9>Tn6C13d`PwLY^h*^%_jAIn{&xk`>4P%U zr}}xj2mksrOAUtO^lD$M-R-i{^hn}f9d0EJIw?i=>Hk?# zNMSwJ+}u3aB)B>F*T00MqQ7=*m$~qFP@Z(i)XnKn1Zj;fB8~UNk3Naw*=yP8NY*7o zw-to^zN`<0Sslbl>CAtcR@VZS2#N^S*)2AexCIAoGTTbqNIZHrkp|{J zST56W){1E7mH_ukp*dInpN8gtEZt58nj&f`*LamaeJ8s+x8heniDDzk;o9Dcx&+T^ z97EiDjNTHk8{0!Vse_6kMG!^ zF<-Ob&>m8hnW>`Ebw7LT{B7t7ouA`#QL^9yxYz9ObhzEaR&PJeYH!YHml-wM6kH?t zN?VA*Cs;0Sify;3Cds!s&-JU)AR zu3T3jI!v;6O1vwiI#w4!W-}z(ik%$KBsOblzWZiq_@)M*Ui?^5Zs8ShC&BvX!jJcBnt7W9o;(}RO#Y|z+1FbA(gt5>a@b6+W4h>ABzwo>Efssc zbHu@$Xz$Mj$u0>oIxG5i-mbek&O%RVt6;6v2wg<)@~gWNG^MuoPauosG1XrWcHjEe zXfPeGTASc}iIf zsdDy*uz23#^eB->ha>j!{?#Lh7ckSiKz2Nu2UYlgwRi5}P=0G4cPb=NiEBjbSj%yvzH0_xszs zYwzoN-#_*r`?}2hHP`dp_w_vMS+mw>-S@q|Pxa-x(4!5-90K&NDYb@g1YhFUjN~_r z3(HlUc<3kU0bhD|sAkwMvlej{*Me7efywC5t8O&MH^gBY<9iWap@+Em$7m?4ms@ZI!^c37lM(;)ibtE6w>nu&-Ujz&Cezikn`P@ z@~^Rl)7`#B$4n9am>jkNvBe1tb0n;tuX)!lE0@d0sp0}hkDe7ecX`itV}(2r5GYd@ z6ajc022#S3#~(SI0(7kbO!6A5ssS1+f;3;4jY`6HUIB&~=*`*QZw`V;nh@YO#j|%Y zCwXp`trJIBSfsdhij5Rb}vFb2OU0WhA1gJc2VB%zR9=W zc*_}&w#iL6nmQ}H)i-&As~zS!WdF8pLT@~ktg10|M7ZSgfu-fWdRMSmBs=BQCi)+I z)9V*e+o2()Qk4Eun3n5mY&_GOrI*;DSn>+4egX=TodnUYi?;@q%KV;>_b*7%f?^?& zR?f_qUSHT=aO)lmTJ~3+L9jr20`VI~Mq>K3;!5-E#Kfbw74>8Gp?S+4d>Qf%JEr3s z9w0!Aa5|N=?#k{nYr44vREz1ku_6k|$g;0W8SJIH`7p=hh$4-|q zI#*pQ(jVQ%l!ql*JeHlNl@C*Y2EKc&X%@4InPRiE&N`BHhjsz$J|4~5&G<9)#yk-1 zncs>$s3$Mp)?6Swpjub(z}qTjMu)MOdZar)knzHDV0sU#qZ39d^xk5NPIwZ$Z3uHA zNXiUxE35CDxMvg+=6$v}V)a(P|psSG_+lAXOHEoGpW6aRO_W8ruSEgnrCMJ`2 zdLcxjQ1dzdV#4*lNQt`GolgVNYN&Zf*=b}h%Oo!kdk3qmE1lYBE(mAY-LK9I*86BU zbN)IM{WT&hX)vhMk>#cu%1LwlT(-BDQqCH9)S!cJ)dL-pt{!_SkZET!KivAT4{Qc0 z4Y!rEdO&OTU)$6P4X>7H3+c2L7?V6{KCy+vBl#PkX1@Jr^B)K8ct_Mdav%n)dA(Uh z;3cv8cAAYqHN3Yb;Z|=FHT$j3q-S5XT$pW%tG;l{$!9zj6VMdmSRiq$kb<*X<<-b! z-2;jtAv-}f{j}oPW!s1W;yWZXA;j;qO7iwWIWY$kK_WFLIV+Wtm(d`OHlO0Oyr!*!rm0k2Q zES_kt)Pgvs(4bj}Zj0k-ZHR#QK538~b~m#$1>|NA*dcfC6EQv^iD*#Ib2vTYIfzZJ zgPVQqCqaTm2BdwFAIXxo6wzoH4#l8AL?Qkj+46P8fQ(HS=cWxW&lL16D5t;kUBiW4stIp6kMsn&b!*9Fr*Rul!83xgwXaOID#9r3&B#9nb7XJkdJj28O|qB5F~B&lD0 zaK)zPK!#;-{oyPRCQZRk=3Xm=_sEy|Oi7u7y-rK3ZkQrez{6G|=PQ-Qos6Y4A|RyW zS{40L+Jqk-L!ECnAGv(;9G>{))j7tOoz@9%|9770_H~%2|;e+z|w>k(;8cY?NZ)XScj^+9~etPPGpdzYCxo2s@M# zJQIarjUZ4ljp8lo+5BD<@zi<%-V~fvb6Tw)>G$CV&Now+U$c$LBR-Thi>=hD44lk~ z>AncAyjt*BI(ZPQmaNp20F~;=q4n&PW|Fz9jnr@MHYE0^x9J7x=UNQsx9Tgr%dW~| z$5|VVoqV#q_=7P)cT|p!w)7tCi>URFm70JkpyJjlD2|%Y^40vwf{_#kf}(Gbv!E46 z=k|Sf&3|LDrZXDME5-mdub(CuKw1vHwQ7#aDz~SyllL$N_D+GiF+nPL91gc$QDel(VXOG<0VBLpYsKuX$^534>-cDuqsqVJVJj5=Bdc3w*eTVowoa9OT!>wBqf`b(9?Naw{#{d{%Jkr>$Y zZi+eQ{la3!2VKnCa+nlaVl6Zkn_F6#OUF@%x~K(n*~DdRAeS8w1%3TWTE6RWQG9*1 zbaw8U@mVsAs}AAJ3SuH=O_g+yvRzV1hP$_%a9)EIZh04`YOC&+N@j)1>vyfW zpZ+*n+*wbeF8J%uPx=ggbEA+6i@iv#)%NA#=uoIv|FN-|8#%*-V%&uO2H9(#gE1#GSc13@k zbfV8TX6Mxsk`SdopS5`gbVIT_Ch`fYIqg~^SW;#R=fE<+w;Q$*B7{;}}-4-4g zg8%T4qNPauEEz%H*#@ODy&W}H+61{s)$r$2^~AY(tcTfj1)VwXX>)6TlS(1=^o zS{G^^JXI1gSx!S=;tu1Vzyf+p-(H+)eSL{sWu69ISXfBIwbpmM_MLZvOeA`fHuqGl z%+etb`4{O30i0!b=Br~g>8?n!=9Pr7D9NxP6l}0dk1mDAAIeRJ_|#y8nkg2KT2X)h~sSiJ!i zWpM0yM{m*m9(qOg=rJXf`De?yT^i?^3s><%CC?Frvs<_K)Mq7C2hARj2%afN$nK{f zC*s@h_n#RiC956yeHrEs|A8_r)FSZa*=#_S1S7lzgV5mJ~6|eA>xmN>k9H{ zXcBx{#}Z9xW|V=_1gTyRxKJ@=#JHMcRpRQs_E7Bz`NRe92aS?)Ja{ z(GrXvC~*?#PjCE#PiPC%<+jAj26i3_^+|YhA}4J+Hr(0A$H%ebLcj&4?{3jkJtM`_ zshRDa5q4o<&rZMe+41?HSJ5fb?{3WXFQgpIou~1i5UI{WjD`Q^P?g0o^5TN9Vv$&3r>7s`%Y(aj6*!dq^fFi-D`e(`^m2H61P7GLO0|=|+!w=?%MA`3)%7xrCT#bv!Ky|aZi_S}q zD^ph}E_?Zw)hnglsORh2y_=uF^m@M^$Kkdc*+8@^59QB{(C9Z@jNx!+?%Lpp{i-I~ z=7zCOf31+KBCwHkuqeIGhbz~$W12^>%G^rh!)H5@sJ)>?G#aX!Lw*qqY8tVqSW6uL zGjf2rk#a5tM$>?dEu8c#L*FF$7U$b}ENPY#t&F57kE|1-W`tY;QR*}t>^yE{WCCwg~n|tPUp=|KFY!yjp>oXqg)6hFjIW*{lZnRPf>Xi0EDYy^pr6Y&$-KCXu zHv9CbC3bfy1vZbDSrP|fe4(J}M^YKu^9#bv5&u13z9-`p)q}kd)Qr-T ztwHZEfm&N)aC_8#9R+95@R?!S90NXiG2uWmo0Z8y}QZxMFScg_o)%eS&~wFWCn!=ycH^U{qza>sJU6|U>msIDMSL) zi4%hi-HLB`%+EI?;T%1mta@(`A1|D1YaLJjdQ43Ikb<*HrID4!mG7VqLJ!2Ol59V3 z7Z85~9@^^{SHS9`8}vF)v(u*H#+4u_{4O>_PC(oXtSw6StH=Qpung%iOY{dv!P;aj zBi>hlS0D#O%QhTtwBbg#+4!ey3=SLP;l`Y@F^z7J!v-w<`}pv_3N#l818iT{0{A=l zvy=Up9|DV{^#=#Z*=+9^jCH2b(=p; zFM*fB{6Dp-e|7$=+}U5wJ@)*~`Ttq`>{sW%YO?(0Tt)Hk6k2{Y`&AC)FS9-+9-jXd n2l<=Xzmk7gH~aImPvxJBLD-mYT33AF*$lqvph>GS>%aaB=w8H! literal 36255 zcmcG#19&BCx9=Nu><&Acv2EM7ZQHhOci3Ua=-B8a9a|mS_Dy=NZ+~mwv(Mf8KF>L+ zCv(nvYrYy|RMq(Z>YZ|upkOFKAV82nAAhf}%Mz>5KtO~dKtOQs`$o2g&ep~@PBa#d zwl*hP>W)~f$gh+%JP;Zyp=)+F?3Sc7BMr2zuSO%9S}^R@)OJe@82kR%p*c2i)!bv6r+asP`5RufAbA|}g>+pT4-RZLt z-wC<0opHnbd$0jSh_5_-mUtFj&huASgPAa^CG1SX>UsIyhMKK{P6vrq`@q{+V+)JON3~VYkykdvIRIT%jfgk2cn)#B z5bm-HdeGa3O>?nFp^Rk6P61z$@QO%914YIQ(j8d4*JYqN)1EdNKGuwvhBHB;WYvdB zM#T?E5y&P$a%q$XU@@sQK^G3#!ORR}U`8bvG02!o-;( z?p`Bz1>`cEe9DIp0AdXwu+xf2gC$Df`!Qu@#^$NKy2A28sLolDi|8NP1!PgkfO4*D z!G~*t^hvQciKr|J(}GVhe?ec1mY&Nbh73P0;&+=CVk}buu0UPy@Ssq`IcT5R4Le`d zuVxOHWkBEg}7a$R| z49ft~VfX-PRM8xgQi8pi5jr~7lkDVM1MHrZ*-@gP?4ZIWl3=P5JbzvyO1Rs}DO!-( zJmDU>RGGCAB1lnray#=XY_~AhAv2ofI>cMM`-FT`wI84a&k5hYj~trZmNnBJmGAnr zl(RLRsCJ@{-QVhOy{v{lTsNO+Khzw=MPoCB2Q$9_K6^RQ~Emjeq{ zg9ek2#Ouqc_|G{c^is>H>t`Y%9FD{LixOxvF!?{ykJI2g?wmO8ZhuMw$4}k)0zSrK z;iF2EY2k7OLgaOEWoxXhnt0i7v$-B|P{x&VET52*@ViECsMmn-SDL>8FGHaKfsh!e zTmoZ|1B<)%OlQhX>r=l;)5dp;pO4C)Iz>{!a#E$`SrOJA+B2m6dYdQ#S*(OSQmQvd zveuv|wx-mQ(Fc-Zr_iDYKu2)w4E-s9#qq!rmvksD- zW-87#i^4z(VTd)Wh;|}KloPDvLxYOOC98XsjS~glHS?km((v)i_7J_eLhc~-LRtLt3 z(pzbp(%Muu`m414VT7J@#x`YMFXJAI5XRLc^uML~Dky z)rdlP5f4Qz(@?@D$Lz*yD zqK#ZCv$vYtEKknM3F4{HS8bf0w2zK?y@3qVQe{4D`ro=3e*bDYGj}*^k_S;1Wu+_< z^Kv21P>6u()xvP({EB>U)&cJHb_Cuq^jHPvzbcJu_UMo}o>HTD@~I%fJ|B`^09s;( ze?Hd9dUdnjaM5PUishwVDZtJ@DjfEF9Mh;ET&$D~`Hld|TGUkaG4cI6q(kj$Dslc= zLvA{v(&^4?3%YD>Yhkp0`#mE?bt^ww{Ae$70r*lnT}ePrl^=M!T~x+AieNjMULLhj zCRW(0=kY8)Tr8m%oEVdPGe%)s09LPeRI^fvZpI6g|4CrzjK*dQri}dajGaKzHuMO5 zki38Nz^EKSVahd-K8g;C2d`W%@Bvo%$#nqY<4fNib#JdXXjBef)>o{x*er0bjo(w0h@Ar1N4ch6O30o(SCj5OgXY6D9EO3#F7{pJ=G=?M#cQoeXlQ_uh0;U^D^Z zhJz6LLmyYt^Ngqwh9cL#ShRv*%qk=v$ggipYn5R8(PwZf$i4Va%NEBp~3C!p6`hu zi7JlawiYI&Ha*&=`0I!XU%hk+%cECP=hQxZr7ZV=Mh>}bQIpPeT^t!vA2EFSt}`~! zzeW~e?#yUeWu&9<)t(~7mX?EuVqSIK1h{%!tEoK#Ql=qKON>e*_ocET6B=y^R|tsl zlu^7jcN9=CM39X6Q=)i&4c-q}icJ|x5`_3oq< zjd8Z*%@uj9Eo?($>htZ_qWN(M5)4bJ>g^~*eSm6F3n*!<^QjDFmQy8X#M7SO^}VQj zCmf+Jo(X3ccv`A&*i;5xZ{Jo|h$oO{;S?hYc?9&7bqsqFLX5xz-;YouE%$+0;Dwbk z^W76;|1~?2;BY367$ZA0L?ycyVwvk_>J7}vSLCqUlOp|C;|tM=-mn== z53)jiki>8C-&XHeUe6-oH|AA&bzYtoJHTh#&2KtrsyM6K+FCW47a6X64;EaS$^s5v zUs!jGjQuIM>!JMQ9%8(&fq}g+M=??54;<68Lq*BZ%P= z$mlg}VVMe!Uk8-Yk(LL(x!Oocz&?37F6nm-h_TfodG>iBP6mdBN07SOEd7wRe{pnS zziY;|wfSx{(ip?je^u4a*-D?j>g)N#A_9WMbEQt_4MFZd<-t(W5;7<6dGMwZ5D@Kq z9&D#?YV1hMD9FOkD8$4{Ex^VuM9sv&AWSVFEGR_H$il!*$Hd6MEX>OGcc#4Tu*`=1 zlAM$SM{5HX))o)=v9)TH5W$@ux>|}t-HkktQc6&|kdyT4jnx*Okd3(*&g~LH8xv$% zFzIdgC3=5kdzvYF#NpDTHe%1jfhm0__wwp3-P{?O4}ZGH5IA+nRoRcN2>((L2S8HN zlO<1@MB~IUel^p#*qThfNikeEY$+5&B92KsZ{m{TD>XVxL0dL_6v;*{t({0xo}B)Y zgg$)cuF`*S(h^%-l5ik1mg(hTZW0&}E1sV9&E&F$Vook@fVJ2yF-h62J)#bC)VnS~ z!i#Bmlh`XQiFM?Pi<(rrTbxjDzLn1S(lcSqIVV{ei4+r(YN4?WuVSd&CH=feYx~G) z7oDWT3oA9%0~p5>YQBhErZ&>+@^Qo{gEn@HN`2tM!dXj2QAsDmqJ^*AiMvVrR$~Tl zt+#jvtD7)10`h4{{(C6f1^Xq@2AN#X)ruVB_(tN`u9?C2%Hs9P3a=uZ`t{$dUnX=| zr02gDu&S7oGMZiHu4|y)u0GvlqYl^VDl;l1p^r3|wRX3m3s-J*dws${l43lmf9M#p zZZi4pQWz}08(EgKN0F`^`8e(TatHp})2wI-`_-#_x#^)|(N9?Gkl&qGOMSJlRe*{3 z$%MLeFLCHw7*ZaRYK#!gGzR;3lgX~1Md7dg`Z)C?kCJ4ci-y6@(^M261# z>FsA?1?9n>rL|ecH+NtiCDgh3ki@gOm7>6_9t|Orp97D@jn-N!HAbwizP3 zEga0spCZ1t+4_g;<_7>C2A^USrY_C5u| zkMY9WkQ0HAB-n)5eh8#K=)M(fno~=BaDB;5{<7^yCw&nI^a+4*oXDSr_&B=9mY|S;?l&|Tx4LBhs6ym$dBGZqLYsP1Cbsc{-kIF7WHU&tn-~r4HEQ^f0)i5qQ8=7Xi@(UZ zMO_;h4yWmCp9ef@{A3`lVhOL59Ly3Vl6nj)acsHyB!4J%d8|=$wc+$eVaFTP04qtk zV`m2^rj{_6tUFeM+HPgZ+ldL)Ewnpv>AikODyZPTHpj&~Z0-%T zYref6wA@>*Ek|T9pwL}~o}O(fqQJkU+ui5&FymCJ>#9MoiQ_NOgKETK zGS<=EEY5)4P`xc`c@NDmO3gE*aw;;7SykJYCpSFfd{SF!#o2+-=_9B_bX10nm)R%8 zQ^YghdGbdifF*Bboa!FGS2?IqKk!GFxQ04=J<p4+a2a$Zwc$eiR6+|3Po-k^X& zBzbvrn5Fhgic8hc%Qh6Wg|%O~i!XHQ)CTq{6?F$_I9p8VrXv}|ifLQ7W%a9Pt*Op< zryfkecy$D7x8q@U^aDWxV!!n?AAWF4w^gz&d}m)vG%bRab0U zrh(xiz%wJZ4g~4wRF>^Lifty8)tB?FK61`N>K%sKOI>}sCL!A_cU`3AgNwKZ_W%x| z_E1ar=a99nJ;)zogcR|SF6%eXb~w@;oz9%?X=3_GvoV4`5UazUS)i(00`?31mdV`j zYz9P_1+Nde!rx!tNgoOq+t!Dxy`FV7C1aLfIk5Vqv|ZIRA$T4xamm~{fuE}`=cQKS zs(H{%vhcDz*TE7Dryq>qU4y4<7!L&Rpk=14rh&iI`s`nM|A2>{9R{F+kXCUc8<~UgrC2`o^cm&){6c$IHFr9{gL6tIe+cB)(~nDSgh(SR!P0 zg5k|6%<7Sd;n)$`fH<`vTKbz8ny2AI7b$OEx*O^TLt_mt-R1-sy2CKLKEl!Xe0(98 z3<4abG8{y!$?xh>72$*bi49k$)Ft+3gryxtreYsJU+E z+X4z+g7WilhgTzxLll+AnFI>ew@%&)9!q<|z4A0X^&It%?V$ft|$43OPC5Wn#J@~0~TSTyXH_YliNp&W6<)RyamX)b~{9OpOklxF7X#DI~$(Scw&=o zZ6(cf*8?LEOgdz?Hic0XVY6_H53mJ271{Cv~oEJ%IIVXv0jxr-4w6%VAst zuT_nlc^RIIt!T};%l#@=GBB)_jy0g-^N6^Mn}PMG8xgX$p)H|;u5Oym4$8PlWU`qa(PT(0HI}ehCi@dtA9~$IAFnP;BI5<7Sd^R5#Y~_bRtgk74~oe!-ZCG$^Ap)2#pv5Vp1`{x5=H ztuieX4xQhVL(VIYZ?ilu)$Wj(_cM_%H)dx|yew6n9+50>5dS%I7JqwdZUqMdy2Acv z<}4&kC&bLg$V4qj&&Ed0#4f@{%`PCqPA$mF!a&EuAjCq?%KTU6tfuL>+>H84iOYjU z&L6TSk|85SfwgVF`uy`T~M`h**YLj2P_)B4DT@d!P8WjW`PlU16z+j8w8MCtvwg4q&R?$c1x z?vBB3CDoa_GsAhjtJiyH66LtyUs?tsE_KI zW3*#gaKXstE^>b?6e>7r$kTM0taHbVUnb2YemkFY<;Q^iLQ%3o@{>o z&RmZFOLj1f*0c*po`oCZWzNlByE~!NC&MeFX?)2Bbv@^RtZ+$z+iF=?!_~s>K`1w% zA|T`P_p&GPSfl(oQK^ZS;t~HiXq6K;7dLz-=l!Q2MZ@qxJ#HR^<@DIhCsTRR7i z$EL#Ux3Ntdk5E5}6K;e5h!u+$@~a~gu1Q@|=kFOMq_Hx{Z^=8%DP>2{{4PDPG2YTc z!j?hd-MH%?2@U%+fu#tPdQ_|mlNkaG`b|rYZyHID_%i@kg=^8aZ3O0ivA3m?i9WKw zIK7&Wa?Lf-r|hX06G+*kUf(t*tW4(8t<0Ogj?NIwSh)3(dsZ(z4bc5b(!BLcpk*v5 zuLKP|VOOAjaYqTVmJ^;$3$c#;gJcW(b)j$M5+s2^6O-Q&R_vk4|Pl^14a$VLIx9G z1KvQ6=7m1?3&rga9k6HutujGUX!+BA^<$JgbdKGDD`SEpMR#Oy)T#y1rR(D;U3AAe z`;%Nzo?2~zgc32iAQ&@btK$N?3z+SGAKcHhlszE6Ih9~HfoYVK@6I7%6HYe;Whccy zu2V$c;DU=JyKu}R;(K`07JR*h2(U*(>l5@rMk;|~;TO+(B)ceBxf0|JY{(6jk|FhM zoWD?3<0=|G(LJ2J_vYpUh>Dv5-EmJ4%m4`5`#EkG zmL`63j|0{-C28}!Q%N1# z+L0##MK9KnPbVjzEQS#bf zitfyWxl@(WjZO+EJ{=+#0*+|1xbgs4fv}OqjuS(%N(wgmr0x{7zaMTrjGFIA){3?H zQOg~;`=RBOGi_K+m16C1GAtPH^Hn$0dgGT>I=)>rG~jT|rz}>xqJ=v-N#VP;e6P&$E?>!tO?b9_KKRniIgHa#709(UC6`jn>C*`ulKWC#hFz z7&E7`ZRsF2bSI02>}OkLRSxYuFyosxELL0t81V627oWa1(_`=dzJh!^OS}nKcphYb zL|f_LinuMdt}&}3Mqx7)tQ$e`b|du(@Tkhb5d$)*Fs&^E{4UQX+fbo(8+`3?=JuJ% zRJF>`)+DV(FCNv9m3`g$w5Y4Yr9a-@*5zgkxi)by6G&1~tlP}=sTW7kfg#{7H)JYx z;&RQ49dR};4b)cF_{Hj0V>{N+vtG@adP?MWR@R#EVD!0|GXa5D3^Z~06^#SAm{BLg zPriXsUe_x%(bcu<$#w(r{dyuGS;mG+sGaLmn^`@$KCe(6c^;RCP`s`$XY8zw&_zdv znE_y7XiS6C&GmeNBdcH6GjjyRYti&e-x8QWs170@B#e(HT!$CfG+@|3A*sg7`bABH zS6opZWzk~gzAJBN#+s5OjllhoC(S`O(b?qtc93g&I=>t$aQqfZLSUdVr%34w{MUUD z=?*z%o*v*OB&cWEl+}PET_CM{>*cq7si!(Nk63YpRP}9>e zLKFAxT<#owyZSoOHvr89paa+%SU_`e0cfR+ZA_ia0L<@23IJLWb1Nrfhxd0YeJ5if zV?$dbV*n2iw4;-QvA#958?bg9JxmWBV({H-1S^T)w3e7=D+SFeMN@d7(5Fxp36$pt zoh3gx8@C^x?(5xS7<2_3LIPo5iwyjj;c^TRE0ofMID(Ko!P%$lX|Rr3S+q}Q?`(>xfz1JsKUn#hy_ZER!o_ekGAeN6CURv+*5%NDEPoXU+S)k1A9n(#A&S`U19Y08P60 z0(ur^06n`l^t-A4?&hP~zf3IWU~8yo>;%w!??p%iK&$lbIDj^QR?ybU)=c7+wvyYs16@O!Qs|Wahb@J3YNb zY@qJ;l*Z4fb(yMDj>K{9%{QKaRgefA2wHfSh0BKoeFr2-v92GJ;SKEPbuu|a2t5N@ z9#nn>!B$_D)$O-k%GTkuRFdtyFY3QA+n92qTIJRyGY`XqIIbCVjsu7{1GL-(t)O%VnrR<}+!i$AHvJ~>gJ+ckUW zTwKTXQGDSZ@_16dAUPh-;g8BuU$;80plwG3x+T)c#Hs5@RtBoK2It$^sE|Da09}3p zs$a{x!VR&~N$A^zC54GRKDKfM&b6eW+-H5t4Y2*$8Nz;-K63h`!dZ;Y>rW_-%4jUS zQ~a%1QfPD(7Cv>{=;aRaZL5pjd~CRvDl4}O{UUf@S$;nWDk$8nHJHm^Esn+rI>>i+ z!xw{v6av#H+Y-ghSr^DVm|d<}9Ae0p8%U54l*oqH1H}7C6OkTzsH4rSGQP?&mciq7 z?-371E5c?&il0Dn_ZBwR$bmSY3bSB6$f_FzIS#_Rco4IK!T9vrqGqaElP04T^$ z3=uR1ltv81oDZy)pJxFGnxB3F*d@@y4rs>TV**SjfW;163rw{O&JG6FPm~Wjq+5~> zc+KA>=uL3$S+(QX0s#KHLIOqu*jRCpM&L&&Y2fH`FW$^seO%iDon&_@*B8 z4Xkq@s$kuoL`c3NNYF_UHAt)rA%QqGB48wZ%Xor9kW%4{IQT-WAJJm*_S>M~p?Ugg z7-$2STcPSv8wM)+a|RN0vuTEDDpKgXEGCGI{tp2~2D3HAYNQpsE>J8;nbFjJDtfVc zn$@W_pbPrPoY?S#U6`BLc0SD*S`0SK-@%#?=A&Buj(XuXNG{ykDArKU0uZ_#&kelr zJD`2BeR0=g@di3cNn{dH#6yVC6^O{w>;09)EeNzpxJlaa6NfpBL>(~H`E+Ez6XgPQi4hWb<&wxq zP-G>rg#{L6*d>1Ox%0UT7Ae4$*vzPvrL|;h$hHf4OL)_YCNid8rEU#ZCYHxrCLg7G z63Zsdr@E%<(&Uor;`>Ux7C$$G$anK~EBY5ytK^An)c0@)iwkGuCmVzrWEg}S1a30- z%M-UH_$M?W%a-yTR8J8X;eQdBE^?o0u9vRoSTbIs!x3dIe40)?=)cC>Z@-2zCN|dG zA=|;;`La{@Qvtk(PVb&k0kbG7F{(8x_KIou$N1LxGE0@Y&RZLK@&knpg;z2`vPm*< za%`EDvh6I&Y<8J-nd}Um1&M{e#iGU2EKPaz__uM_obha3rnl|q(8KDMaF6Cki<{m< z?!&|{8DBcSV17~llFBr|jG1ARF`TiJvBxx6Z>9m$0H(2{vDctOmz;h&s$@c37s;Mi z`TgV@^(0T>YB_hMVM(2uX@N}Lug}^EG@7jZOv}&}vRq|(fJo34fxrLpg zotnNsyCwijdXfB@-6eSud7b(>`UM+?gk|yNlN1FS1)KwHhK=?S7d%^B;tAr> z!_tZiGiyqEE#vj$u$H@KBuwSZt%Ld1E9&YMB6DBad%1?Z3fwavC}FrG)grUeR?&2+ zPN)>AkErm}$<;rpS=S#{KlU#5Wmsw(dJl$JY#G-5Dqh`fs4S&kcj-Lw=FHHpUPWt_ zX&t|Xza@Agd7_8l4s{D{hre5Jav^IC@}5OH+TUpYbrH1%LF!3bGcEpYJzM=3`7gL% z1u(Ga=jb!k7!H&68_n1b@iay>QMzt+c{9q($y*vnkE7D_(R(g^)_toB+>0;GPm~Cf z2=StkgGt{K_r8q7=!B(Ksm7~TH6`2`oLQWG237&J4_yc*0;U4N1H%A?{K*-tw;Q;-H2{xxN|#7$1`R~uSPh6{PC7Dbdv9HMAXkQwek?Zwy8@BQ|A;R}zla)xA|8 zR!47xPTGrZi=JG6yFj|GtRA#nsihmJ>nu)u|E*oQGkTeS+0?3f+@YecX|IQ19%~d^ z&rnj^E>UG6I{WRg@X-HDY{qW;p=Z-c_R`?;eCN8g?=)~UXg>rGE(&&=@6er`WhK9L zzy8WbMeq1g{$Wd}sjsfD(23YZ{J3baXwhI#tn)1A%sgueYZ6OObizQ*mi?gZ%kLXO z&(Gxta*PE(?!nmb*)KK+@A1xZV7V6EBfQHFNMCYq8z(d(H1g(F=E55bST@YD5PT6CjvmUP>crDhzde=xz54sw zh<|F8&czRh(&hH2XXVs#)9>usoZi{q?I$5G(Q~-1IVrlwKIR7vXV&cpc6Bc)Ta_^# zpS<@TwV!C$Zd<%}V&1Z`KqJ8)PiZ{rsUuN&;O-kFZkH60Ajn{>l#)dQt(!M1>RLS;!8ZRBE6sZ?E6s;5;k9vq&^{Bb- zKOc!oo!$!WB!6wZOP(yx^>KY_H#HdUJGY!XO6QeWE9qc=oV&H&Guq#tb~QgM{uZ%T z-obn8|C0A)cs&?@a4dT-o17cX>*@vdeCbAFZL+(57j*UXzb4&(($GJtHVZw&ztYu@ z#P*}?JqH#S6co^RG&TZ!q_7GA?SFlR{-3G&zf#)2^YQ;qmr%#h!+_Ak2H!oQ+FC() zid%WEltFG1KrHr^lCiA}tDoOxmKhDD4tmB`q*dpytBRC<1u*pW&6s5xMXiwe3eOmb z4)lVMEL$yYA{h_Ja6%Jd=Y68WN4RWyRwJvn6JZ?PSMKMyj)7TmXXoK|2=Me23TSQj zat+S0lY6px1R`!Fg#9lp@iF?3S<^Ez{l_fn|1SGT`Tr*Zg#K^E@gEB0kDdM@L7@Lg z5O$Ui1@aGp@TcDYDG9;=p#P%~|FZ_6|Cd+)AtdSlXqEq7X;4SkKnK#H2;ceiVjwtfBb&C`N-&th;&{e4RJ7tkZVhj{6euZ#OK<|H3yP6LvH>n!2Yt9;QOOAD_hgQG_~X3V*1~j z^xxx=ex+q$`f$_7#>CDJU}R(aQ~IYKBi%b>__y)@nCL&d>%+kRHsW7K zmC?6;M+W~Jqg&~lzI*lEdLK0f-th;tCN&EK8-SXT?HzzHurj^J5)0FNEQ!Czfw>{S zjj5IK`_O3l9SuL=3OybB`_4y?AA29mo!+U3zMYt{xv7~GH0%2ni&oLe*jnYIirQbL z0A@y(_xdiTe>?`Rfit z|8CoNqy4wwt5VI=N>SZ|cW>oL6xm?#3{kN8S9Er06)2HCG6v{C6=D`2GROiHqv2N2 zAP}gepMD%Pq_gIBdW?!j=`4@ZO|1Ov_nBFGr`|17#hHR-^91G+46 z*ve2z?MIui&HmwVt03r;Tho}E)qcO5-g5j5Y}i%2d@V=51uN%b&B!A>6cl z--$W30`!9g>2&+p)cqHw#H)Q+y4Qf-DjRdHDtZSVQf?Q^fA!I(cjN*L^rRT zD@*mI7z7iK-S9PMnD|c8MkJ4F`U9}xe!dzUM5%D=#1UwH2i2XFg%HFajz}oF83i?> z)RyQcVl7nR_?*}?k;44&qFyS3hIf56=hT>xJZFVZlx%13Q;Ikx*lod|SXU=U9LX;& zgUBjRWzo>$?5=(*I2*_GBXZ6)e&_x9@RzpI6y`+^O)~z1NexPS!@lU`0AeFjGWUA5 z8RAUp3Y19tQVb21M2lwFajJvGfckxM^I63(&>N))@!5%u)JCnkEE)590bGb9+=*5t z$;AjIa6vUGOXbQ4P>WV7eK2-aviB9QSN#Dxu&B)GTq<1}aRQcEc!_9&OH-2&C2pU| zDTTO;K<&AeQ#P+LhbhkmG{6m~Ow6_|G+Qn^e#-QM{UVVRW*|3~Qau>})x?rCRSe97 zJJyW)<~XUb9xS>6;)Re}Z>3DDs3X;;7Dtz?fhfb$F646UQ0ybLjLt>ld4Ynv26-|Z z+9(HgPzqsP37vp5BiP?9C)J3>j9=^UBP(1y)E|gR+D06&xVdY;G~bHU99My}FwMyz z6aF(Y9Hi3kMyEnajfO&T2)@W+c*0l~rBud#oyCs)^(gVw_*}~E*xBT6#A{r|GnR?X zgRS6<>GYJgtb|`=vs4u9%F6<_CvJ%=u~K9k>Qd;15PC&rL$o-Y7*iK&iK5IC9NYma zUuOvj(u3X-CwQ{UXvOrR>0{x;rV~zlyVzOFyA7+qd|nI=a5^NXrd*cus^oyCDN43` z_Qb)-VppS3rk-7yD`~@py9FYlHMkNooHCtZljpS~`9fy_JtV zQL-3j!)W1>zZ|UrGYJezHe;VUhm1JafIqBT3?4q*O^Wt{6{%ZBE0U`gWksb^N$Y|o z)hOy4eD4ByUq@Ah&y$beCt442fi#PRH>uMn$`o}UCW44J$@5-{cY(wVORe81I|@{R zLrfjLl2U^9^Xt@C4IBm|Dhk8>o@_Heaiv3;WjR{eeI}$gRhT4wsnaDf>bsHbKxUXb zV;Bshq^?z2f~)7t>b!nwUs1imx^Y=h*mU$3QIFj>!>irl<9Skx-j&cW5hPx0pAAA{ zCSi91lC1$b08*l1=P1f2E&m5Lg`Q`9Yq8A20f;2U*~3DfaDK%uIREYlbGm^a^7(^{Mq4(N~uq$hp+b_MGO>_ z8`w;TVRkBJqi7J(e0p$-qn z%|wvL2}UB($;i+SKHlK;k#=0n&@p|%n80nQ1}eK*hi2qVHfb!S7zPA2(qc77?!)7Pq_F1X%joBv|^AhC|gBGwrUwPVrc;`5(|K2{9l z0J;9EAT3Em{DpN{1a~wqMpsFjhOMs4#Lm!eG}ISza72_=oGKk7Rh5RF?lTPTbtk=2OIRy6P7S_wY;FSYBhQEvv0Pxo9WpoLx+ql z(vt?Ya|5nZ((Ty|)pH>W;JM4vYm*aJ#+vFe-s$ZlO&3)czNqZ-sJu!ZNvcWfsyuz) zocc!IRJeMY+_368P31p*Zq3h$qeO8D)_QqHn1gPszg4{0zfhCd#`T3@bDQVgVfPBP zGzA?F1E~NT6bzko_UD2}{f0slL~?G8N}{>aUN(kzBl@`c8o$wO*|*bhXbRsV&?>Xe z?)Y=j#CPn1LD%zH_uH@D_uo+Eu)5yXY;4P5p;Pc$?NEHy5?-Q0+xD;F)9KzDmf<;Z za$AMZo!)bJV9u=ktb_36ty4Z$K-nU>*K2qouYE`CcGj>w{loS2#pDLwcAZz-Thz<$ zW^=T^YiXQa)Aadyt$qG2+TpbSz|*cJ`cq;y2x?cnbA-4&N3wb9$ZXyez6aNK?`^IZ zQ4iiK($(HL?<)(g(aU}D;!od!0IHr-5>T06!JrEZ&A})8XeyGVsud}{?gv@aM9f0^ zH4KuUo+61!gk;x#RjL>dhqM&;1`Mz5Ne>}R%V^iyE6>gx7)&);V;L?JEcbAKkvY8# z^7PdFUC4`!hl7O)-zQ4w5j%^97x??`$93~;S!{IlVBU@U3t{KW;}6vo1qg?MaJjpm zzjRw424V_4iy2NYhLhv9e-))K_S-!T#f_-jH`BJY+{SXYHYnzuTyzk|ixIA+_IJ{u zADOI+acIU7=c=kHL7<}*A-$8)CgyRaWNQ4Z9ImeFFyeB8pna6-?zUraj6BmQAklB; zrBv!a^38%o%p4H{D(>6hUL`l2TQMD7Tbpd*y2{~GISraV0e#Zv*ZX?Q0u0cC48W_x zC%O~#+#4koxE1@Xv z1SU&9=VOPf!K}!Zrps?;B{R#8_&$oGg^JTX4_K_WN{OkYcRKraNjNrZt){*XSriyA z1;-(#9Gp2T2IvCDd46(AlVYI=l|f2!t+n6V#-=J7D#c_}bI{n)*hTZdSoRxbYTg~> z=(P9RETi2--H%E@GaU^pSJ6^XCpP@J?t?oCqK~&Xm#pb0w1w}hZ`NHo3^yLIxrjv& zdhFd;8`>Oh==@!SWN6v6tNmo!;pn7iax#wf8cFu-T32dR{u>&!QDWMY^)Q#({@Peo zr#~nUTH;Z9zNRNt4ug9vcr(|{gUchdztOqZbXwQ~yxFaMFL~18;PznOY2NzvqT9dY zigf-p=4cNBeD1YnaU}A*Hyjpg7+6WOz>k_ttfLTwFk05tiEa+*c>mH3|d`{i@sFy>FJRY=o5)Llc*1VbAq|4>cpW+XXtRb`?m zbaMmO9s2IdZ&qne8Ob&fcvpuQoE2|JK-W!&HjP_J#r@i?43of}9S z3piWW)ze-Iuam2iUVTc&_=B1Ut{-89Eayrl0p)qffw&U(L)3)QK9bvu2 z_pNfA=iyM5_u*Lk@f!e+2TsWj-{+-$3!-WaR&gmArF?f3T8wy7zBZ z!ovQasRSFt|C@6BMJE31*LU6huGar!`@=U_-f0vI<6qo^@ttSypa0mr2rVOb+vp|-V(!D4Zplk|3?{1dwpX?KRoF-!hXhJhcYf7%}ydBs{-N zJBm2`r-*#Cr+-RVp*NR|S|Zs;3yMAK(lW-aQOPDfghj9oXzR4&|!wR9!Djir3X!AJ9^y zP_LI|t$a^i+c>&y<2^^!)HM=LF=RJ~m}{r>R!J{ulYi(Efz{h-o${ry(C$ssYoSu&+T#M=Vmf8>U)- z4ZNVIsNBdxver&iKhm#jq1hO@PhzpSi%R96%pqK$fRcMAEn>{EwN2buG(LB<_Bw~HH&Yh7UE+l5r%rGY6ED0X%mQ$)f zFcz1HEb^kDSaN3jT9(huF6iSwiCk<(_|7b_3QNxQFspEoQIW{HtR{2nXA+7cT)?O) z+C0Dq<=~fu2EQWC`DY+XDJ{MA%x{^cwibNC3 z3K#<5vjbb?X}~o=Egbn$av45^Nviy+1pLc4ayDoti=IUD1zxz5z|zM6uoTQIb4YuI zYQfAb$JQ@i9F&aY-YbZ>)Op3iFcDSig5AVQFw5(=9_*H;;X=a{t{jA$3PcN`bk5zZ zx_l?udnsijcc=A$lggmcn6V2pkTfL%m|-#Fb#Iuwaxea*-k=PRurxKD){F!YiJ`^sRk5;x_q=ArP&?@5pzI zLq^7hj#~>xxl7M(h2_tgqdbFub`~7rmSOPKz;%$18hi;%z_CjOhBYIwOvZe=9@E&e z2Og7ME|QGXrf&v{OM7_p|7q{L!Vg(fyloF995C|re zPy!Z;io#YDlqxoCG?89H5m2du^b!FfbO<4#gd}%`v)y~k-uImI?tAzC@veO2%gS7H zjM>H-bIvh-W3D){h+dHb=!Vg48{jhET8*^NS;w5I-GI4u6EOVTrGK%Udm7wP<-b=X zMfUw3SM!Tw;!ba*25rfnBd2Uix5b`B|;mwM))Tc)wV) zTYS(b5iGfFH_vUqbUJnB;F}tkGpRUvD{;*Z|Ifn$g?9KgB~Qt&C!a1!W*8ae z$A?}dDvh`B}X6>9nw^d7r zYtK^++U6I_0tf7bttfA9pCa$v7I5|0+xQ7=@r}kAZ?@sB!ww?B=)wr3izJ@xvqvnN zVH}tec|2e7%cdbLMrC%OExfrm!2U@yZN4ugG5P^Rn$S^UK(+mFv+jQJnkXL!DeIV` zp-$n#Vp9vV_sCnP!!%(%IUg0!DqHe`PTlM4T-w(@{cO?PDtM>R-sD>M%(6-!uy$$q zAu+4VE=3cq3s&9@>nx5i3oHA++=GSz-DA6lyvcxI?m?{ZdILs>(T z$I;2L@iE^bA0s}8NAAhGYa+s`8BDv>Mnp56DNAB}%DVlFRjQO)!p+1{3-nfYy4M8{ zM*cTH`q)r&zfg?ui&*t%>`Yn#uZ4{UHk*FRMMG&pAq{ z9_np=lhK&!C!MbJD-TIpUKa{FhS7Nmwr3 zLxu0`#DHD-pI{Sv^epMw&=~!eU~D5b-0cT+-F>~s zNCN_bfI%=20tAJCz=(4okP`6!N6zo={XGZ+BN)sO4pV^{8yKs=peS_}eI(de1!8Cj zF+v(64Up>k`(a?Pk@^7`Tm@l(0&*fjFckxRLxhR}0%Z(Gs3VMw^fk0gM@TxQzi0c4fl@G*qU_|@%g5atuHpxU!T*{D|7#zpBLL_5YFc$JIN-oy20jIl=D>xAGw}2&>{q}8Z3k`#0MRA;0dNnwXK=_Nh95?g?$nZN2P`uTjYVr^Ezt;xHiNV^hC<_G*5b$Fq zR!Bhu0{)Rjz~3~1i^}+e(Vv^^^aJW-Rc!(kJOBU+(CQ!XKHN5~bOsoriay+r=S5;{{qGvC>87y?&Uhl7CZ+%PM1FF%YUFpqe-*xOl7CSV{E8`($_aq0VWlsAq-|@qz_eB04N|oROVkv9SZSZ6uSR6 zG6wtqTEtdK!k-_HRk!}DLh{eVc(ni>fPxP|^id!cBoqR~(i_1b+_eQt1p(7Xsp}&l z1|UOyt^k4mX9UR1;~>_@apigauG{`=dJ6eJCPTm3+W))s6i5|<0G3a15K0{c_^82f zpk==)F5ngv4nYBHNF)MSIs$rXzrugg zl$x5KvE%A`Ky?EUQ$Snd9PPPNpwCJwcXkBKtw zwJNuWe`7`ee^msL_~StuJy1UBSY93;-CuZk1c6nHH{KDqvMRZM$1Gw8ctaKG@B{q2 z4|j)j3(n?-%dFSNjB3Yk7}dKg82zm&EO1^U)Sxr0LT1B(n7--7(Y6x^d6VSJsCAj? zpb*Tab2d`0r(brYdGz{0&6uoMznBIafI(~+_mpB78;FQw-;USVFCg&qXGwYD^w7JYsQ=W`>1{z!gHrqSki z!+aBa9y{J0t28I?&JV{1W-N*wd-v^Drm@-=(PtO#lx;a@q!QP`f4$4(L*FKiy$uAv zn{wdVP<4(7pFO7ho#Bq^>mPwnn+@cKQd6JG1jaypV_y!`s>^7qv0)H80m~b zAA(gQnqo&NscWwv(m>X?Wyz9<>C1!Qhw)MLQ7ufc?(%15QP;0`?!W_hQ*Bd*lJ($u zXh>I*%|s|&x3)~FR_=%bnE%mZzAc{(AgAT!Td$@|Zf1QAB3_WE^B!MY9+o6`IP<*J zuBblL{TcmO;-wMX-peCe9eobh`@}O{kDg6CwoZ4aA7|~4qZeMCS>FYWUifdL$6Z&h zj9%j1BT?OQ5}_QS@n0{LX}zsn=Y~i$f}TLSOLkOmd!2g&qva|wM3PJudFKA=OfNM* zkkV7BeeKgcaYxy@o%iwiZ_ZwO>IO0m-M1}08m4?C_Hm)p=B$k_Aj>OHwDS*b%-L=@ zI%#Qk9=~p<^UaH&>~=p5ld%5<8try)Ys_`Agzc&^h2;#@PsdVA=Xxbv7%>V^bI?c8 zd)D#?Usi*j_z7=r{;)GlX|0;ao=&N&vNL@|;jeG`4uYS;+MBkDqw#n2PJCOlH_63- z2CId$C+XqHF1XKB`kJKc_tu;1scZ;`QBKJA^X)didEyn^q^?IE6VA^WJK$Mh6oxpM zdiD4NB?G;^LcES=4nDw#ZK{mhrB!05g^unhQeNI3w)bF4j+m&k-k}fyE=L;q{LB^T;Lk)~{9;d3aekX)?LTZfZh6Cp{)by{jq4 zy*;d@Xj($~326|#w~FaKinb%=n~sfo*y?I_}JLQ_bNO*B;X^#Jwft&=>KmQs-7Osyd)L9<{QUN zO*XFI4jeYgv+>YDqmw*5yuLg7U|&FJ3$l56+X`AT`RvqvChSNdFXp zce0niIN@~Sy06g&eDe3#D5tD7$T}{muV-{d^yOYTmCKJMHhZ_PeRKJ|&1QYQ6MA>{ z9=>i1)+ih-{Brwa9^V@aDeecFDu-` z{){z}d}{rlr@pC9FTuqbbkRQIeu{?F{aE~U`5HX$?B4x@IHs8vQUHN&1&Mi zO$F?0ZVRfxs-_^me8jk`=!;EXo7_rmC;0}eqc&1wg|0~O$rPj>e{=peZ@prjX_hXl zZUN*pF|z)7kekUZ-&@r7uc2Wfk<<5-%?;+f<(p3Pngx5G&b->KmZ_JVdwJjm^>g6` zvmO3(x6-L%5jy@wq9d;^9MOc*7QSVc3^ zN5qa#?RvJjrLH-{?=7};IKeXzUh^Q!tYj^@{I2wsksXOoe7$_-n>OqhmomBY|>5DqI&az&g2OT)T-oRIyjfFIgK+n*j`M@tb-gOrSnLh{U&Yqa#!qwG&ruf z`F%CYzs4N;Ie6ebYzo!jYKBd_j0<)nQbt>gNK3YS(YucwhL`~2SCJ9y?PWglq|!(8 zmVlYoqC?SCimtZ81gAbDT-%r9l~1jXuRu|fB$wt!#r@}}q^oc5kPH*H(VBCy)yFlK z%s0?=!ZunxC*BKg)SfrhEP*`==7@5dTcM4nLeYaXOdfdoXz6iDB3LxwFA6dY2i|n?$TYd*mae{1#IB3-4Hj>e~39 zSQs>>gjY$T-{7Me^Y_o310Ut=i=ocN(#a&-h4Ev^kk_gtn6*E3ZGWT{R=69(%3|zg zPBMpPDB~t!4el{EK9>3Pm>rdo-NBDpORAbt0!T8!MtxeuIqZ%FS|+_@_-5wvO#fti zn-Wsj+}c$)+|Y@wP=w1tg0s;SPs~_&tY{46u~c3+RakCU#Arw zW*);9O-8m8X$vFsvYh;VZwfzs8Gpa84oMEQ!_cn#wZhxhEBY*+vKo->c746gV@Cus zCWzAB&?Y{+W6n0C`@#wf1U0?Cwvwa0NQq!qxiFz&3WMZqS z#^SxqZf8bZKh0**um)(v{hXd$+bb|mMp}Eu$j8+8d0>pHc0gUMLqpM2VUdmV;&XKl zT}<{_HGayMOl;hMUTT;RYD$VLaQc>G=VhMm_9km-1Dd>`7@zk{Izp3OIJLCnIgwc6 z-R?3i7pXIB(I2TfyvT2keN9E)BMWaDx3|{TBgta6L5o8(A8mX+*jtAAp!<;* zQl$+^L9B`wV3##|BGE+Hp1DcUL1#)TN3uXO40kh#5Z7lgl zhE9~{N!kdp_4FBGPHXX!(}!Qn-A~kv`y}bfsC()K$mk?R1kaR*R|qO4X;pU5>C6Xq z&9~iX_^fHG!Jd>|4lk2hPcZNnE_W^T*HW384T&|J20+4B>x=YtXmu?%+c`tSiHfAz z94sQ$IB08w7VC>=+gVD8QoKcNad3%u1*2a1PHjd$B;iu^S(_!97Bb<>i}8vGwbHGn z`SX;x5?%2m>`elRSlSaaeBZ*h)t3G^Ld_*u;ksJda(7x@s8u|g3c-DQ!N{ei@tA51 zeeopgP77VzvRz^c>8lr|HG6Su;ljWq{Uk?8qvnX0@44MM9ya5C-)t@V@LH3!4EFs6 z{a@CVOgV<*i!JfjvN@in3lkJlN2&2lJ1G~v(77o*M=ex~9THt36F@9g&Jo0CPaMV4 zzKndf3s3ZMmlaGVEN8@P-XrIzCHIWu1H!GaMI|N2wAwjEEv8uKh^PV0*l?L3^@+vK zlFFO=RAn0$SlG&A_2RFof}O{Zy-)G?zmaN^Pd?^q@aSN1p)-nKRf1pN@Sj?DJ2d-C z(=)@U;b%cqmYD|D6Yl%Ep75G*)1mA#Z~qOYqz61lK%cE!nDs{ZLlRntZ5ypHX;_#nF%1vZ0qMt81T z$PEsfeW?^jN?Yn0uSm7|$ZsPyQgohFO}JxmTh?p|d9~;r7@6d}HX-Jr^OFE3LWb;r ze);t@SVm}1>3seXjVmLa%8UiuDP{7Qe6MO6EJF|w4BI0UVJ90Jl}ZG&F2+CwxrVPg`&XFt6V>69332xp52(B_kto@44i(m_tk4`$|GPYa-G z*9KlGlM>i7k1E5pzT~4~Bde7-TPC1`XgUQ-;cFz#STlEe2ew8EUAf0+TKn|N8;3MY zBVb-3F!MA96`OQu^Da6`8LSA?J`u+@e*M5+|K*57)I?cy;AkjADd`jzff%12+n2MR z@Xgk3c6hhmql>&5G0GaYm7C;_zrKvifcxRa<&M9*j8prW_OlOu%E8ZP;io?MsS|(B z3qR+^pX-CaT_cr9^Sw^Xb?sOhlqG7G-k;V#pS#w-fdRJxTU|lRGHXGOpYCPW*d{mn zL}A;jOXsReDs!!Z1H1A97Vel-RK+fX6MWgBc0Ku*T6B_UuTAFm?w-)PP~+LwNqK7R z^W1IY2w6A5x8W?5)ioHUE0f!OiSjV0UTIu>=0nNlI!Sb3R%XYA2yef;+VcxX^G6%o zL(8v8j?JFqq_174_U^c))5B+#+nf`ngMzz8kEKM3FoS91{Z{;egXElNPs#JoV$mLy zo7uhI^SzUAENqC!m<2S|{1->aZXKD9UCVjoDRG-~HMeP^Gat00r0z~$C|w*DVlB~y z8g-bM2kMtD6ir@!1fosZ<=YUj0#z}p5aTQ%U|OU50#V=yP#h> zQxVY*m~bb`5ru$X>Lr3ATG_h=;{V7 zFMt9Ih77DJNdeOvwf*M=_Pxmr%#KxZ>ToW$A(s*>akVNts&7k6$^?$2G@QgPFhAEU z?=9|;uqzJa6p@9yJ!sTS&K3S}fPtz}RDNHec0d?YmLPX)8`P)k+%NpXnBD<*3(L~Z zMsc%{EPFK5pK|kvN`b=zEk_*T+Z_|lWdGjj%CPz#xu7UP@!cUGqj!hi?<+W&U9D(0 zHv*nas72%z(55*8(Qz5|6Jqmp8d|D1$mPAMX2>y};!En2bI=O+JTiE4EPM7Q188dS zbp}-j{$?Y+MZW5sp6tq-$L{#3GAEd=49;9~uUizuJeEa$ z>{*u)DMV)ViD+0n?4S2;_d}~QMxJzO-dPA;xQI)eFCnR1=bCHOXJ-s64eF(hir+Vr zIc3)>9y+s9STqa39~F3^JFODf_=zDp&a)VJN|LXBQSxRB>lBroWEpC<=leUlSW<3n zgJK0QdHGxsY2gNU`xxk&r`@F)!dRb8O=h#0IleN~S6Ou)>{|L{;>l(F{?D?@Gd2Ak zPJM)ei73gi@c3!4XIWY1#M{cQjAT|gzEX!t%wa7lMC=y>-k5=$3_|-2-Ji)L^>)SO zq66u=SSL|Z%{37niI|I1){^dR5drE`NTm?VHfp3&l1`U*UT=3!D%#gaCrB})zh1g) zTWVrglFm{Wk|83y)VR@5>)Cv?VeocS_T+TM!&FW>YYUq7sZ>6lR!Y|aX_A}0A)7tV z?QS{W_sX5<^;)I-!c7V#d?Q*paK=zpIJk)3=E*=&a@UHJrq9Td5mJlUPn-%u8z*y| zA87gE2#tH)LN@mm;LLN2!eedyU!vgeE~>Nh?JNJ@paegIcJK11-WmFE;z>o3#aV6Z z*_tEWnn{(yx^G#u+rb6O6EkBjSN;?0((tCK73?Ob$2&?lIW}mULw8E60#rLtA z87G(#^*XwxlZ?r}!MIq~=TJL0%tH`fc`Q$e8L3ePJ|Q9DNq! zN?MLcmfaKsRD32>jfi^lwhJ(rikrCx4~+Eq_-q_doNJtBJ@ZLlxVWq+yXe{B(4tbg zj#F?cAhn>%Dc&b0VUkR)8*l6Oz)n3a-Qv@AiOD#1x>#I?b5*GFjxNVIpr)9nUI-rH?FcWgo=9 zdQPL(A#lBPWC+2veiTA{+2VWuD$I=!V6%kKOVbQj!*ErZ(znx`5G#*Dd23I$ zY{lIps-GL)I^jzihQ{2|H%i)iU2?;*L(LoQGqS43CS9Ui<1MPK1F5_EduRlpN$W+lX3o29HbeEc_keZgnkpv?<{IL%nal}7qAz=G z|BK;w4M|18g{)Ee7-I4JWCNLiIVxi?tKLjFN@vNEnZ>Cq;%bq4kFJKn#koV#&y&zm z##_~>)&z=Jqnod4Ft&l>k=b9}?`*<)i=vcZ)E7g@Aw-U|E7dz4%A#u~$Ft|31o?S& z%-VN{yv~s6)Ol4hHy~88_w}2egx5*_N$N>Uqt*kcKEgxw2>gevQ%?Cu=P3~Xf=D@`4OP?s;zQy^OB;S(PDj5V;uWq)L<#>r(n6yvVu0W^x zk_sE&-d7!0QHz-wuyTqz#UoMeax~ntj6N_>5o~=i1I61d8D3ya0$~TCn?WKm+ z_~gd}Qik!GpBEgKNw$6aIl(2Rx)fy)O;MwMOJx8HflU3KvQCiCh|v z$GRko-pVLq*Vy=m=CoNuFrLG&Rpv%+ z8T3BSPRH2r&-T^D{n2CCTv;?{9xw~Br|HS#(=zBq(IewUWYi0l1ah*^fub{7r$rl6 z(z6?w6>tl-^2F!m1tJl@{TY6=x5#3FQO+OcmcC@Z6+Zik@$9OJ6pFsQl&ng6tURe1 z*8(StkTmH}8;;q|Gn?y=Yzz*V73{Cxk-jl}d4#{e>v_{a^kcKzGQC;~eK|yU-HjSf zp*C3>9h2WqVR%fhvCV6W4^+_cE2KEj3-3$M4^$tVCv8Ob5^S#P?!pv~?#AM3+e@XA zPerEsGkPhcZgXv_uyPV3pAomO0v&G-1-fp=%_8Y`lny79vmQyFZC`QpSl9%)bU4Ot zl23X*W_@ypS6gBtptknu94f56o>&otUi9DU-AnIp37BXt-8=k3F-o8}-lFck=AgK# z#x6|p=kRmM3(<+S#rvAvKRSkysEv8FDNNP0R;i43k{IE!UqK(qcHreTdBb(#H8S!3 zGTuuWHL=pFg(C`f6}94B21#r;>fpkYrH*08aO$Dvvo>2S&tLJmozJdImo!V6b7hD& zDyQaiEuuG4%TFXw{_*wf=-&??E#WB9l(6#J9ZM=;Vu~`rA-% zs$HAt%&ys>wka`sda}?DFehr^GKByP#ZK;=rkq+OAS(B3_+?z9B7YIrS$q=Ey!Toz z02qr8hI$2*JJ)PP<@DrUUdEYyasdNm-{c?l&_0x_a>-8V6(|k8+X`SXfV2Cj{Jx!+ z1jr8Vebf_;J9i6!X8cgv@u@>7l>?V~u4t{f7a)V`SPPKdUB74kX~Gsopj;WgPr#aT z;wnIPXzjg#lco`yfO18E+L#FY=mTU=feb&Z`?Gg{3d7Gw?Wbn=sds-)6F(>6pKFGn zE3*H+3&^h=-g7(k4bFZes{x2?oHO_`{v=hEy?7M;UR?}7Yqx0mOz^uK)d-D+m5!*%~))_VM(GW#)j_dDC~1G74w=8q1DIQysQn$={h13CU6 uJ7mSf^Ltpwce3w2vKs#XM{q-Ncf9UxD From 1cbd8a8ea3b6171e827e90cb4f4d2e89f0f69e4a Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Wed, 2 Jun 2021 20:55:52 -0600 Subject: [PATCH 177/404] Corrected the configuration state-management field. --- lib/interpret_and_optimize/helpers/pb_configuration.dart | 2 +- lib/interpret_and_optimize/helpers/pb_configuration.g.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.dart b/lib/interpret_and_optimize/helpers/pb_configuration.dart index 86dfe70a..e97c6ecd 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.dart @@ -39,7 +39,7 @@ class PBConfiguration { @JsonKey(defaultValue: 'Expanded') final String widgetSpacing; - @JsonKey(defaultValue: 'None') + @JsonKey(defaultValue: 'None', name: 'state-management') final String stateManagement; @JsonKey(defaultValue: ['column', 'row', 'stack']) diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart index f453cc0d..237c9a53 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart @@ -11,7 +11,7 @@ PBConfiguration _$PBConfigurationFromJson(Map json) { json['widgetStyle'] as String ?? 'Material', json['widgetType'] as String ?? 'Stateless', json['widgetSpacing'] as String ?? 'Expanded', - json['stateManagement'] as String ?? 'None', + json['state-management'] as String ?? 'None', (json['layoutPrecedence'] as List)?.map((e) => e as String)?.toList() ?? ['column', 'row', 'stack'], json['breakpoints'] as Map, @@ -23,7 +23,7 @@ Map _$PBConfigurationToJson(PBConfiguration instance) => 'widgetStyle': instance.widgetStyle, 'widgetType': instance.widgetType, 'widgetSpacing': instance.widgetSpacing, - 'stateManagement': instance.stateManagement, + 'state-management': instance.stateManagement, 'layoutPrecedence': instance.layoutPrecedence, 'breakpoints': instance.breakpoints, }; From 82edf72312eccd0ded778f3b44bd0b7b50c6c04b Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Wed, 2 Jun 2021 20:58:19 -0600 Subject: [PATCH 178/404] FIX the bug that was preventing the imports from being printed in the files. Finally, did small refactors where to improve the access to certain fields, for example, being to tell that type of tree is, etc. --- lib/controllers/interpret.dart | 26 ++- .../generators/middleware/middleware.dart | 3 +- .../state_management/bloc_middleware.dart | 154 +++++++++--------- .../state_management/provider_middleware.dart | 146 +++++++++-------- .../state_management/riverpod_middleware.dart | 69 ++++---- .../state_management/stateful_middleware.dart | 32 ++-- .../util/pb_generation_project_data.dart | 3 - .../generators/util/stateful_nodes_mixin.dart | 17 ++ .../pb_file_structure_strategy.dart | 3 +- .../pb_generation_configuration.dart | 106 ++++-------- ...platform_orientation_generation_mixin.dart | 7 +- .../helpers/pb_intermediate_node_tree.dart | 45 ++++- 12 files changed, 313 insertions(+), 298 deletions(-) create mode 100644 lib/generation/generators/util/stateful_nodes_mixin.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 99717904..0df68a89 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -77,27 +77,21 @@ class Interpret { var tempForest = []; var pageItems = designPage.getPageItems(); for (var i = 0; i < pageItems.length; i++) { - var currentScreen = await _generateScreen(pageItems[i]); - if (currentScreen != null && currentScreen.rootNode != null) { - var tempTree = currentScreen; - tempTree.name = designPage.name; - - tempTree.data = PBGenerationViewData(); - if (currentScreen.rootNode is InheritedScaffold) { - tempTree.tree_type = TREE_TYPE.SCREEN; + var tree = await _generateScreen(pageItems[i]); + if (tree != null && tree.rootNode != null) { + tree.name = designPage.name; + + tree.data = PBGenerationViewData(); + if (tree.isScreen()) { PBPlatformOrientationLinkerService() - .addOrientationPlatformInformation(tempTree); - } else if (currentScreen.rootNode is PBSharedMasterNode) { - tempTree.tree_type = TREE_TYPE.VIEW; - } else { - tempTree.tree_type = TREE_TYPE.MISC; + .addOrientationPlatformInformation(tree); } - if (currentScreen != null) { + if (tree != null) { log.fine( - 'Processed \'${currentScreen.name}\' in group \'${designPage.name}\' with item type: \'${tempTree.tree_type}\''); + 'Processed \'${tree.name}\' in group \'${designPage.name}\' with item type: \'${tree.tree_type}\''); - tempForest.add(tempTree); + tempForest.add(tree); } } } diff --git a/lib/generation/generators/middleware/middleware.dart b/lib/generation/generators/middleware/middleware.dart index 48770f94..4e325c44 100644 --- a/lib/generation/generators/middleware/middleware.dart +++ b/lib/generation/generators/middleware/middleware.dart @@ -1,10 +1,11 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; +import 'package:parabeac_core/generation/generators/util/stateful_nodes_mixin.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:recase/recase.dart'; -abstract class Middleware { +abstract class Middleware with StatefulNodeMixin { static var variableNames = {}; /// Using chain of reponsibility to handle the incoming nodes in the generation phase, [nextMiddleware] diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 6fd972cc..3e492f74 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -24,89 +24,91 @@ class BLoCMiddleware extends Middleware { @override Future applyMiddleware(PBIntermediateNode node) async { - var managerData = node.managerData; - node.currentContext.project.genProjectData - .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); - var fileStrategy = node.currentContext.project.fileStructureStrategy - as FlutterFileStructureStrategy; - - /// Incase of SymbolInstance - if (node is PBSharedInstanceIntermediateNode) { - var generalStateName = node.functionCallName - .substring(0, node.functionCallName.lastIndexOf('/')); - - var globalVariableName = getVariableName(node.name.snakeCase); - managerData.addGlobalVariable(PBVariable(globalVariableName, 'var ', true, - '${generalStateName.pascalCase}Bloc()')); - - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - - managerData.addToDispose('$globalVariableName.close()'); - if (node.generator is! StringGeneratorAdapter) { - node.generator = StringGeneratorAdapter(''' + if (containsState(node) || containsMasterState(node)) { + var managerData = node.managerData; + node.currentContext.project.genProjectData + .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); + managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); + var fileStrategy = node.currentContext.project.fileStructureStrategy + as FlutterFileStructureStrategy; + + /// Incase of SymbolInstance + if (node is PBSharedInstanceIntermediateNode) { + var generalStateName = node.functionCallName + .substring(0, node.functionCallName.lastIndexOf('/')); + + var globalVariableName = getVariableName(node.name.snakeCase); + managerData.addGlobalVariable(PBVariable(globalVariableName, 'var ', + true, '${generalStateName.pascalCase}Bloc()')); + + addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + + managerData.addToDispose('$globalVariableName.close()'); + if (node.generator is! StringGeneratorAdapter) { + node.generator = StringGeneratorAdapter(''' BlocBuilder<${generalStateName.pascalCase}Bloc, ${generalStateName.pascalCase}State>( cubit: $globalVariableName, builder: (context, state) => state.widget ) '''); + } + return handleNode(node); } - return handleNode(node); + var parentState = getNameOfNode(node); + var generalName = parentState.snakeCase; + var parentDirectory = generalName + '_bloc'; + var states = [node]; + + var stateBuffer = StringBuffer(); + + node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + states.add(state.variation.node); + }); + + var isFirst = true; + states.forEach((element) { + element.currentContext.tree.data = node.managerData; + element.generator.templateStrategy = BLoCStateTemplateStrategy( + isFirst: isFirst, + abstractClassName: parentState, + ); + stateBuffer.write(generationManager.generate(element)); + isFirst = false; + }); + + /// Creates state page + fileStrategy.commandCreated(WriteSymbolCommand( + + /// modified the [UUID] to prevent adding import because the state is + /// using `part of` syntax already when importing the bloc + 'STATE${node.currentContext.tree.UUID}', + '${generalName}_state', + stateBuffer.toString(), + relativePath: parentDirectory)); + + /// Creates event page + fileStrategy.commandCreated(WriteSymbolCommand( + + /// modified the [UUID] to prevent adding import because the event is + /// using `part of` syntax already when importing the bloc + 'EVENT${node.currentContext.tree.UUID}', + '${generalName}_event', + _createEventPage(parentState), + relativePath: parentDirectory)); + + /// Creates bloc page + managerData.addImport(FlutterImport('meta.dart', 'meta')); + fileStrategy.commandCreated(WriteSymbolCommand( + node.currentContext.tree.UUID, + '${generalName}_bloc', + _createBlocPage( + parentState, + node.name, + ), + relativePath: parentDirectory)); + + return handleNode(null); } - var parentState = getNameOfNode(node); - var generalName = parentState.snakeCase; - var parentDirectory = generalName + '_bloc'; - var states = [node]; - - var stateBuffer = StringBuffer(); - - node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - states.add(state.variation.node); - }); - - var isFirst = true; - states.forEach((element) { - element.currentContext.tree.data = node.managerData; - element.generator.templateStrategy = BLoCStateTemplateStrategy( - isFirst: isFirst, - abstractClassName: parentState, - ); - stateBuffer.write(generationManager.generate(element)); - isFirst = false; - }); - - /// Creates state page - fileStrategy.commandCreated(WriteSymbolCommand( - - /// modified the [UUID] to prevent adding import because the state is - /// using `part of` syntax already when importing the bloc - 'STATE${node.currentContext.tree.UUID}', - '${generalName}_state', - stateBuffer.toString(), - relativePath: parentDirectory)); - - /// Creates event page - fileStrategy.commandCreated(WriteSymbolCommand( - - /// modified the [UUID] to prevent adding import because the event is - /// using `part of` syntax already when importing the bloc - 'EVENT${node.currentContext.tree.UUID}', - '${generalName}_event', - _createEventPage(parentState), - relativePath: parentDirectory)); - - /// Creates bloc page - managerData.addImport(FlutterImport('meta.dart', 'meta')); - fileStrategy.commandCreated(WriteSymbolCommand( - node.currentContext.tree.UUID, - '${generalName}_bloc', - _createBlocPage( - parentState, - node.name, - ), - relativePath: parentDirectory)); - - return handleNode(null); } String _createBlocPage(String name, String initialStateName) { diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index eb9b59c3..cc82a8b4 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -5,7 +5,6 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; @@ -31,33 +30,34 @@ class ProviderMiddleware extends Middleware { @override Future applyMiddleware(PBIntermediateNode node) async { - String watcherName; - var managerData = node.managerData; - var fileStrategy = - configuration.fileStructureStrategy as ProviderFileStructureStrategy; - if (node is PBSharedInstanceIntermediateNode) { - node.currentContext.project.genProjectData - .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport(FlutterImport('provider.dart', 'provider')); - watcherName = getVariableName(node.name.snakeCase + '_notifier'); - var widgetName = node.functionCallName.camelCase; - var watcher; - - if (node.currentContext.tree.rootNode.generator.templateStrategy - is StatelessTemplateStrategy) { - watcher = PBVariable(watcherName, 'final ', true, - '${getName(node.functionCallName).pascalCase}().$widgetName'); - managerData.addGlobalVariable(watcher); - } - - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - PBGenCache().appendToCache(node.SYMBOL_ID, - getImportPath(node, fileStrategy, generateModelPath: false)); - - if (node.generator is! StringGeneratorAdapter) { - var modelName = getName(node.functionCallName).pascalCase; - var defaultWidget = node.functionCallName.pascalCase; - var providerWidget = ''' + if (containsState(node) || containsMasterState(node)) { + String watcherName; + var managerData = node.managerData; + var fileStrategy = + configuration.fileStructureStrategy as ProviderFileStructureStrategy; + if (node is PBSharedInstanceIntermediateNode) { + node.currentContext.project.genProjectData + .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); + managerData.addImport(FlutterImport('provider.dart', 'provider')); + watcherName = getVariableName(node.name.snakeCase + '_notifier'); + var widgetName = node.functionCallName.camelCase; + var watcher; + + if (node.currentContext.tree.rootNode.generator.templateStrategy + is StatelessTemplateStrategy) { + watcher = PBVariable(watcherName, 'final ', true, + '${getName(node.functionCallName).pascalCase}().$widgetName'); + managerData.addGlobalVariable(watcher); + } + + addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + PBGenCache().appendToCache(node.SYMBOL_ID, + getImportPath(node, fileStrategy, generateModelPath: false)); + + if (node.generator is! StringGeneratorAdapter) { + var modelName = getName(node.functionCallName).pascalCase; + var defaultWidget = node.functionCallName.pascalCase; + var providerWidget = ''' ChangeNotifierProvider( create: (context) => $modelName(), @@ -81,52 +81,54 @@ class ProviderMiddleware extends Middleware { ), ) '''; - node.generator = StringGeneratorAdapter(providerWidget); - } + node.generator = StringGeneratorAdapter(providerWidget); + } - return handleNode(node); + return handleNode(node); + } + watcherName = getNameOfNode(node); + + var parentDirectory = getName(node.name).snakeCase; + + // Generate model's imports + var modelGenerator = PBFlutterGenerator(ImportHelper(), + data: PBGenerationViewData() + ..addImport(FlutterImport('material.dart', 'flutter'))); + // Write model class for current node + var code = MiddlewareUtils.generateModelChangeNotifier( + watcherName, modelGenerator, node); + + [ + /// This generated the `changeNotifier` that goes under the [fileStrategy.RELATIVE_MODEL_PATH] + WriteSymbolCommand( + node.currentContext.tree.UUID, + parentDirectory, + code, + symbolPath: fileStrategy.RELATIVE_MODEL_PATH, + ), + // Generate default node's view page + WriteSymbolCommand(node.currentContext.tree.UUID, node.name.snakeCase, + generationManager.generate(node), + relativePath: parentDirectory), + ].forEach(fileStrategy.commandCreated); + + (configuration as ProviderGenerationConfiguration) + .registeredModels + .add(watcherName); + + // Generate node's states' view pages + node.auxiliaryData?.stateGraph?.states?.forEach((state) { + fileStrategy.commandCreated(WriteSymbolCommand( + state.variation.node.currentContext.tree.UUID, + state.variation.node.name.snakeCase, + generationManager.generate(state.variation.node), + relativePath: parentDirectory, + )); + }); + + return handleNode(null); } - watcherName = getNameOfNode(node); - - var parentDirectory = getName(node.name).snakeCase; - - // Generate model's imports - var modelGenerator = PBFlutterGenerator(ImportHelper(), - data: PBGenerationViewData() - ..addImport(FlutterImport('material.dart', 'flutter'))); - // Write model class for current node - var code = MiddlewareUtils.generateModelChangeNotifier( - watcherName, modelGenerator, node); - - [ - /// This generated the `changeNotifier` that goes under the [fileStrategy.RELATIVE_MODEL_PATH] - WriteSymbolCommand( - node.currentContext.tree.UUID, - parentDirectory, - code, - symbolPath: fileStrategy.RELATIVE_MODEL_PATH, - ), - // Generate default node's view page - WriteSymbolCommand(node.currentContext.tree.UUID, node.name.snakeCase, - generationManager.generate(node), - relativePath: parentDirectory), - ].forEach(fileStrategy.commandCreated); - - (configuration as ProviderGenerationConfiguration) - .registeredModels - .add(watcherName); - - // Generate node's states' view pages - node.auxiliaryData?.stateGraph?.states?.forEach((state) { - fileStrategy.commandCreated(WriteSymbolCommand( - state.variation.node.currentContext.tree.UUID, - state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node), - relativePath: parentDirectory, - )); - }); - - return handleNode(null); + return handleNode(node); } String getImportPath(PBSharedInstanceIntermediateNode node, diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 767a807b..599c1b9b 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -2,7 +2,6 @@ import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; @@ -24,45 +23,47 @@ class RiverpodMiddleware extends Middleware { @override Future applyMiddleware(PBIntermediateNode node) async { - String watcherName; - var managerData = node.managerData; - var fileStrategy = - configuration.fileStructureStrategy as RiverpodFileStructureStrategy; + if (containsState(node) || containsMasterState(node)) { + String watcherName; + var managerData = node.managerData; + var fileStrategy = + configuration.fileStructureStrategy as RiverpodFileStructureStrategy; - if (node is PBSharedInstanceIntermediateNode) { - node.currentContext.project.genProjectData - .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport( - FlutterImport('flutter_riverpod.dart', 'flutter_riverpod')); - watcherName = getVariableName(node.functionCallName.snakeCase); - var watcher = PBVariable(watcherName + '_provider', 'final ', true, - 'ChangeNotifierProvider((ref) => ${getName(node.functionCallName).pascalCase}())'); + if (node is PBSharedInstanceIntermediateNode) { + node.currentContext.project.genProjectData + .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); + managerData.addImport( + FlutterImport('flutter_riverpod.dart', 'flutter_riverpod')); + watcherName = getVariableName(node.functionCallName.snakeCase); + var watcher = PBVariable(watcherName + '_provider', 'final ', true, + 'ChangeNotifierProvider((ref) => ${getName(node.functionCallName).pascalCase}())'); - if (node.currentContext.tree.rootNode.generator.templateStrategy - is StatelessTemplateStrategy) { - managerData.addGlobalVariable(watcher); - } else { - managerData.addMethodVariable(watcher); - } + if (node.currentContext.tree.rootNode.generator.templateStrategy + is StatelessTemplateStrategy) { + managerData.addGlobalVariable(watcher); + } else { + managerData.addMethodVariable(watcher); + } - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - if (node.generator is! StringGeneratorAdapter) { - node.generator = StringGeneratorAdapter( - getConsumer(watcherName, node.functionCallName.camelCase)); + if (node.generator is! StringGeneratorAdapter) { + node.generator = StringGeneratorAdapter( + getConsumer(watcherName, node.functionCallName.camelCase)); + } + return handleNode(node); } - return handleNode(node); - } - watcherName = getNameOfNode(node); + watcherName = getNameOfNode(node); - var code = MiddlewareUtils.generateChangeNotifierClass( - watcherName, - generationManager, - node, - ); - fileStrategy.commandCreated(WriteSymbolCommand( - node.currentContext.tree.UUID, getName(node.name).snakeCase, code, - symbolPath: fileStrategy.RELATIVE_MODEL_PATH)); + var code = MiddlewareUtils.generateChangeNotifierClass( + watcherName, + generationManager, + node, + ); + fileStrategy.commandCreated(WriteSymbolCommand( + node.currentContext.tree.UUID, getName(node.name).snakeCase, code, + symbolPath: fileStrategy.RELATIVE_MODEL_PATH)); + } return handleNode(node); } diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 2f648098..c459b439 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -16,24 +16,26 @@ class StatefulMiddleware extends Middleware { @override Future applyMiddleware(PBIntermediateNode node) async { - var fileStrategy = configuration.fileStructureStrategy; + if (containsState(node) || containsMasterState(node)) { + var fileStrategy = configuration.fileStructureStrategy; - if (node is PBSharedInstanceIntermediateNode) { - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - return handleNode(node); - } - var parentDirectory = getName(node.name).snakeCase; - - fileStrategy.commandCreated(WriteSymbolCommand( - node.UUID, parentDirectory, generationManager.generate(node))); + if (node is PBSharedInstanceIntermediateNode) { + addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + return handleNode(node); + } + var parentDirectory = getName(node.name).snakeCase; - node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - state.variation.node.currentContext.tree.data = node.managerData; fileStrategy.commandCreated(WriteSymbolCommand( - state.variation.node.currentContext.tree.UUID, - state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node))); - }); + node.UUID, parentDirectory, generationManager.generate(node))); + + node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + state.variation.node.currentContext.tree.data = node.managerData; + fileStrategy.commandCreated(WriteSymbolCommand( + state.variation.node.currentContext.tree.UUID, + state.variation.node.name.snakeCase, + generationManager.generate(state.variation.node))); + }); + } return handleNode(node); } diff --git a/lib/generation/generators/util/pb_generation_project_data.dart b/lib/generation/generators/util/pb_generation_project_data.dart index c8d90dc5..fb01d661 100644 --- a/lib/generation/generators/util/pb_generation_project_data.dart +++ b/lib/generation/generators/util/pb_generation_project_data.dart @@ -4,7 +4,4 @@ import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.da class PBGenerationProjectData { void addDependencies(String packageName, String version) => PBFlutterWriter().addDependency(packageName, version); - - /// Queue where commands can be placed for later execution - final List commandQueue = []; } diff --git a/lib/generation/generators/util/stateful_nodes_mixin.dart b/lib/generation/generators/util/stateful_nodes_mixin.dart new file mode 100644 index 00000000..073b16cc --- /dev/null +++ b/lib/generation/generators/util/stateful_nodes_mixin.dart @@ -0,0 +1,17 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; + +mixin StatefulNodeMixin { + bool containsMasterState(PBIntermediateNode node) { + if (node is PBSharedInstanceIntermediateNode) { + return node.isMasterState || + containsState( + PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID)); + } + return false; + } + + bool containsState(PBIntermediateNode node) => + node?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false; +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 633ddc8e..0f0bd442 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -187,9 +187,10 @@ abstract class FileStructureStrategy implements CommandInvoker { var file = getFile(directory, name); if (file.existsSync()) { var fileLines = file.readAsLinesSync(); + var length = fileLines.length; var modLines = modFile(fileLines); - if (fileLines != modLines) { + if (modLines.length != length) { var buffer = StringBuffer(); modLines.forEach(buffer.writeln); file.writeAsStringSync(buffer.toString()); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 83f2e87f..ae19cfb3 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,5 +1,3 @@ -import 'dart:collection'; - import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; @@ -51,7 +49,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { @Deprecated('Use [FileStructureCommands instead of using the pageWriter.]') /// PageWriter to be used for generation - PBPageWriter pageWriter = PBFlutterWriter(); // Default to Flutter + PBPageWriter pageWriter = PBFlutterWriter(); final Map _dependencies = {}; Iterable> get dependencies => _dependencies.entries; @@ -59,6 +57,14 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { /// List of observers that will be notified when a new command is added. final commandObservers = []; + /// Queue where [FileStructureCommand]s can be placed for later execution. + /// + /// Specifically, once the [setUpConfiguration] has been called and finished executing + /// for the [GenerationConfiguration]. The purpose of this list, is for callers that might want + /// to execute [FileStructureCommand]s before the [GenerationConfiguration] is done with [setUpConfiguration]. + /// Those [FileStructureCommand]s could just be added to the list. + final List commandQueue = []; + GenerationConfiguration() { logger = Logger(runtimeType.toString()); _importProcessor ??= ImportHelper(); @@ -69,26 +75,11 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ///This is going to modify the [PBIntermediateNode] in order to affect the structural patterns or file structure produced. Future applyMiddleware(PBIntermediateNode node) async { - if (containsState(node) || containsMasterState(node)) { - node = await _head.applyMiddleware(node); - } - return node; - } + node = await _head.applyMiddleware(node); - bool containsMasterState(PBIntermediateNode node) { - if (node is PBSharedInstanceIntermediateNode) { - if (node.isMasterState) { - return true; - } - return containsState( - PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID)); - } - return false; + return node; } - bool containsState(PBIntermediateNode node) => - node?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false; - ///Applying the registered [Middleware] to all the [PBIntermediateNode]s within the [PBIntermediateTree] Future _applyMiddleware(PBIntermediateTree tree) async { tree.rootNode = @@ -104,28 +95,24 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { tree.data.addImport(FlutterImport('material.dart', 'flutter')); generationManager.data = tree.data; - var fileName = tree.identifier?.snakeCase ?? 'no_name_found'; // Relative path to the file to create - var relPath = p.join(tree.name.snakeCase, fileName); + var relPath = p.join(tree.name.snakeCase, tree.identifier); // Change relative path if current tree is part of multi-platform setup if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { var platformFolder = poLinker.stripPlatform(tree.rootNode.managerData.platform); - relPath = p.join(fileName, platformFolder, fileName); + relPath = p.join(tree.identifier, platformFolder, tree.identifier); } - if (tree.rootNode is InheritedScaffold && - (tree.rootNode as InheritedScaffold).isHomeScreen) { + if (tree.isHomeScreen()) { await _setMainScreen(tree, relPath, project.projectName); } tree = await _applyMiddleware(tree); if (tree == null) { continue; } - - fileStructureStrategy - .commandCreated(_createCommand(fileName, tree, project)); + fileStructureStrategy.commandCreated(_createCommand(tree, project)); } } @@ -140,59 +127,52 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { pb_project.fileStructureStrategy = fileStructureStrategy; pb_project.lockData = true; + commandQueue.forEach(fileStructureStrategy.commandCreated); await generateTrees(pb_project.forest, pb_project); pb_project.lockData = false; ///After the dry run is complete, then we are able to create the actual files. fileStructureStrategy.dryRunMode = false; + + commandQueue.forEach(fileStructureStrategy.commandCreated); + commandQueue.clear(); await generateTrees(pb_project.forest, pb_project); await _commitDependencies(pb_project.projectAbsPath); } FileStructureCommand _createCommand( - String fileName, PBIntermediateTree tree, PBProject project) { + PBIntermediateTree tree, PBProject project) { var command; + _addDependencyImports(tree, project.projectName); if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { getPlatformOrientationName(tree.rootNode); - if (_importProcessor.imports.isNotEmpty) { - var treePath = p.join(project.projectAbsPath, - ExportPlatformCommand.WIDGET_PATH, fileName); - _addDependencyImports(tree, treePath, project.projectName); - } + command = ExportPlatformCommand( tree.UUID, tree.rootNode.currentContext.tree.data.platform, - fileName, + tree.identifier, tree.rootNode.name.snakeCase, generationManager.generate(tree.rootNode), ); - } else if (tree.rootNode is InheritedScaffold) { - if (_importProcessor.imports.isNotEmpty) { - var treePath = p.join( - project.projectAbsPath, WriteScreenCommand.SCREEN_PATH, fileName); - _addDependencyImports(tree, treePath, project.projectName); - } + } else if (tree.isScreen()) { command = WriteScreenCommand( tree.UUID, - fileName, + tree.identifier, tree.name.snakeCase, generationManager.generate(tree.rootNode), ); } else { var relativePath = tree.name.snakeCase; //symbols - if (_importProcessor.imports.isNotEmpty) { - var treePath = p.join(project.projectAbsPath, - WriteSymbolCommand.DEFAULT_SYMBOL_PATH, relativePath, fileName); - _addDependencyImports(tree, treePath, project.projectName); - } + command = WriteSymbolCommand( tree.UUID, - fileName, + tree.identifier, generationManager.generate(tree.rootNode), relativePath: relativePath, ); } + return command; } @@ -202,8 +182,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { /// If an import path is found, it will be added to the `tree`'s data. The package format /// for imports is going to be enforced, therefore, [packageName] is going to be /// a required parameter. - void _addDependencyImports( - PBIntermediateTree tree, String treeAbsPath, String packageName) { + void _addDependencyImports(PBIntermediateTree tree, String packageName) { var iter = tree.dependentsOn; var addImport = tree.rootNode.managerData.addImport; @@ -234,12 +213,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { pbProject.projectAbsPath, pageWriter, pbProject); commandObservers.add(fileStructureStrategy); - // Execute command queue - var queue = pbProject.genProjectData.commandQueue; - while (queue.isNotEmpty) { - var command = queue.removeLast(); - commandObservers.forEach((observer) => observer.commandCreated(command)); - } logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); } @@ -267,8 +240,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { if (rootName.contains('_')) { rootName = rootName.split('_')[0].pascalCase; } - var currentMap = PBPlatformOrientationLinkerService() - .getPlatformOrientationData(rootName); + var currentMap = poLinker.getPlatformOrientationData(rootName); var className = [rootName.pascalCase, '']; if (currentMap.length > 1) { className[0] += 'PlatformBuilder'; @@ -279,8 +251,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } Future generatePlatformAndOrientationInstance(PBProject mainTree) { - var currentMap = - PBPlatformOrientationLinkerService().getWhoNeedsAbstractInstance(); + var currentMap = poLinker.getWhoNeedsAbstractInstance(); currentMap.forEach((screenName, platformsMap) { var rawImports = getPlatformImports(screenName); @@ -297,7 +268,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { )); var newCommand = generatePlatformInstance( - platformsMap, screenName, mainTree, rawImports); + platformsMap, screenName, fileStructureStrategy, rawImports); if (newCommand != null) { commandObservers @@ -307,21 +278,14 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } Set getPlatformImports(String screenName) { - var platformOrientationMap = PBPlatformOrientationLinkerService() - .getPlatformOrientationData(screenName); + var platformOrientationMap = + poLinker.getPlatformOrientationData(screenName); var imports = {}; platformOrientationMap.forEach((key, map) { map.forEach((key, tree) { - imports.add(_importProcessor - .getFormattedImports( - tree.UUID, - importMapper: (import) => FlutterImport(import), - ) - .join('\n')); + imports.addAll(_importProcessor.getImport(tree.UUID)); }); }); - // TODO: add import to responsive layout builder - return imports; } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 889e6743..1867ef64 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -1,10 +1,9 @@ -import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:recase/recase.dart'; import 'package:uuid/uuid.dart'; @@ -14,13 +13,13 @@ mixin PBPlatformOrientationGeneration { NodeFileStructureCommand generatePlatformInstance( Map> platformsMap, String screenName, - PBProject mainTree, + FileStructureStrategy strategy, Set rawImports) { var formatedName = screenName.snakeCase.toLowerCase(); var cookedImports = _cookImports( rawImports, p.join( - mainTree.fileStructureStrategy.GENERATED_PROJECT_PATH, + strategy.GENERATED_PROJECT_PATH, WriteScreenCommand.SCREEN_PATH, formatedName, '${formatedName}_platform_builder.dart', diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 9d7ad8cf..d60ea7b0 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -1,6 +1,9 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; +import 'package:recase/recase.dart'; import 'package:uuid/uuid.dart'; enum TREE_TYPE { @@ -13,7 +16,9 @@ class PBIntermediateTree extends Iterable { String _UUID; String get UUID => _UUID; - TREE_TYPE tree_type = TREE_TYPE.SCREEN; + /// The [TREE_TYPE] of the [PBIntermediateTree]. + TREE_TYPE _tree_type = TREE_TYPE.SCREEN; + TREE_TYPE get tree_type => _tree_type; /// This flag makes the data in the [PBIntermediateTree] unmodifiable. Therefore, /// if a change is made and [lockData] is `true`, the change is going to be ignored. @@ -37,7 +42,15 @@ class PBIntermediateTree extends Iterable { set rootNode(PBIntermediateNode rootNode) { if (!lockData) { _rootNode = rootNode; - identifier = rootNode?.name ?? name; + _identifier ??= rootNode?.name ?? name; + + if (rootNode is InheritedScaffold) { + _tree_type = TREE_TYPE.SCREEN; + } else if (rootNode is PBSharedMasterNode) { + _tree_type = TREE_TYPE.VIEW; + } else { + _tree_type = TREE_TYPE.MISC; + } } } @@ -47,10 +60,25 @@ class PBIntermediateTree extends Iterable { Set _dependentsOn; Iterator get dependentsOn => _dependentsOn.iterator; - String name; - String identifier; + /// The [name] of the original [DesignPage] that the [PBIntermediateTree] belongs to. + String _name; + String get name => _name; + set name(String name) { + if (!lockData) { + _name = name; + } + } + + /// [identifier] represents the name of an actual tree or the [DesignScreen], + /// while [name] originally represented the [name] of a [DesignPage]. + /// + /// This primarly is used to group all [DesignScreen]s independent of their [UUID], + /// platform or orientation. The [identifier] is just going to be set once, its going + /// to be the [name] of the [rootNode]. + String _identifier; + String get identifier => _identifier?.snakeCase ?? 'no_name_found'; - PBIntermediateTree(this.name) { + PBIntermediateTree(this._name) { _dependentsOn = {}; _UUID = Uuid().v4(); } @@ -64,6 +92,13 @@ class PBIntermediateTree extends Iterable { } } + /// Checks if the [PBIntermediateTree] is a [TREE_TYPE.SCREEN], + /// meaning that the [rootNode] is of type [InheritedScaffold] + bool isScreen() => tree_type == TREE_TYPE.SCREEN; + + bool isHomeScreen() => + isScreen() && (rootNode as InheritedScaffold).isHomeScreen; + @override Iterator get iterator => IntermediateDFSIterator(this); } From 6ebf8f627589ca9daca42ab2b52651826f950749 Mon Sep 17 00:00:00 2001 From: Eduardo Herrera Date: Thu, 3 Jun 2021 11:38:33 -0600 Subject: [PATCH 179/404] FIX the screens not being generated in the bloc configuration, it was not handling nodes that were not stateful. --- .../generators/middleware/state_management/bloc_middleware.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 3e492f74..3a87d6ed 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -109,6 +109,7 @@ class BLoCMiddleware extends Middleware { return handleNode(null); } + return handleNode(node); } String _createBlocPage(String name, String initialStateName) { From be42816f3596ef167820c680059a38e307a5ebc4 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 3 Jun 2021 18:29:50 -0600 Subject: [PATCH 180/404] Refactored the middleware, where its accepting a tree instead of a node. However, made a subcalss specifically for traversing the nodes of each of the trees that is passing through the middleware. At the end, this refactored enabled logic that was stuck in the generation configuration to be encapsulated in a handler or middleware, as seen with the CommandGenMiddleware. The middleware is listening to the trees that are passing by and generating the correct command, assuming that no other middleware decided to not passed the reference of the tree(see handler pattern). --- .../middleware/command_gen_middleware.dart | 82 ++++++++ .../generators/middleware/middleware.dart | 11 +- .../state_management/bloc_middleware.dart | 181 +++++++++-------- .../state_management/provider_middleware.dart | 183 +++++++++--------- .../state_management/riverpod_middleware.dart | 95 +++++---- .../state_management_middleware.dart | 61 ++++++ .../state_management/stateful_middleware.dart | 53 +++-- .../utils/middleware_utils.dart | 4 +- .../generators/util/stateful_nodes_mixin.dart | 17 -- .../pb_generation_configuration.dart | 98 ++-------- .../helpers/pb_intermediate_node_tree.dart | 4 +- 11 files changed, 420 insertions(+), 369 deletions(-) create mode 100644 lib/generation/generators/middleware/command_gen_middleware.dart create mode 100644 lib/generation/generators/middleware/state_management/state_management_middleware.dart delete mode 100644 lib/generation/generators/util/stateful_nodes_mixin.dart diff --git a/lib/generation/generators/middleware/command_gen_middleware.dart b/lib/generation/generators/middleware/command_gen_middleware.dart new file mode 100644 index 00000000..784cdea7 --- /dev/null +++ b/lib/generation/generators/middleware/command_gen_middleware.dart @@ -0,0 +1,82 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; +import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; +import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; + +class CommandGenMiddleware extends Middleware + with PBPlatformOrientationGeneration { + final String packageName; + final ImportHelper _importProcessor; + PBPlatformOrientationLinkerService poLinker; + + CommandGenMiddleware( + PBGenerationManager generationManager, + GenerationConfiguration configuration, + this._importProcessor, + this.packageName, + ) : super(generationManager, configuration) { + poLinker = configuration.poLinker; + } + + @override + Future applyMiddleware(PBIntermediateTree tree) { + if (tree == null) { + return Future.value(tree); + } + + var command; + _addDependencyImports(tree, packageName); + if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { + getPlatformOrientationName(tree.rootNode); + + command = ExportPlatformCommand( + tree.UUID, + tree.rootNode.currentContext.tree.data.platform, + tree.identifier, + tree.rootNode.name, + generationManager.generate(tree.rootNode), + ); + } else if (tree.isScreen()) { + command = WriteScreenCommand( + tree.UUID, + tree.identifier, + tree.name, + generationManager.generate(tree.rootNode), + ); + } else { + command = WriteSymbolCommand( + tree.UUID, + tree.identifier, + generationManager.generate(tree.rootNode), + relativePath: tree.name, + ); + } + configuration.fileStructureStrategy.commandCreated(command); + return Future.value(tree); + } + + /// Method that traverses `tree`'s dependencies and looks for an import path from + /// [ImportHelper]. + /// + /// If an import path is found, it will be added to the `tree`'s data. The package format + /// for imports is going to be enforced, therefore, [packageName] is going to be + /// a required parameter. + void _addDependencyImports(PBIntermediateTree tree, String packageName) { + var iter = tree.dependentsOn; + var addImport = tree.rootNode.managerData.addImport; + + while (iter.moveNext()) { + _importProcessor.getFormattedImports( + iter.current.UUID, + importMapper: (import) => addImport(FlutterImport(import, packageName)), + ); + } + } +} diff --git a/lib/generation/generators/middleware/middleware.dart b/lib/generation/generators/middleware/middleware.dart index 4e325c44..3259f843 100644 --- a/lib/generation/generators/middleware/middleware.dart +++ b/lib/generation/generators/middleware/middleware.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/generators/util/stateful_nodes_mixin.da import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:recase/recase.dart'; abstract class Middleware with StatefulNodeMixin { @@ -28,13 +29,13 @@ abstract class Middleware with StatefulNodeMixin { } /// Applying the [Middleware] logic to the [node]; modifying it or even eliminating it by returning `null`. - Future applyMiddleware(PBIntermediateNode node) => - handleNode(node); + Future applyMiddleware(PBIntermediateTree tree) => + handleTree(tree); - Future handleNode(PBIntermediateNode node) { + Future handleTree(PBIntermediateTree tree) { return nextMiddleware == null - ? Future.value(node) - : nextMiddleware.applyMiddleware(node); + ? Future.value(tree) + : nextMiddleware.applyMiddleware(tree); } void addImportToCache(String id, String path) { diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 3a87d6ed..c9b55367 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/generation/generators/import_generator.dart'; +import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; @@ -11,10 +12,9 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; import '../../pb_generation_manager.dart'; -import '../middleware.dart'; import 'package:path/path.dart' as p; -class BLoCMiddleware extends Middleware { +class BLoCMiddleware extends StateManagementMiddleware { final PACKAGE_NAME = 'flutter_bloc'; final PACKAGE_VERSION = '^6.1.1'; @@ -22,96 +22,6 @@ class BLoCMiddleware extends Middleware { GenerationConfiguration configuration) : super(generationManager, configuration); - @override - Future applyMiddleware(PBIntermediateNode node) async { - if (containsState(node) || containsMasterState(node)) { - var managerData = node.managerData; - node.currentContext.project.genProjectData - .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); - var fileStrategy = node.currentContext.project.fileStructureStrategy - as FlutterFileStructureStrategy; - - /// Incase of SymbolInstance - if (node is PBSharedInstanceIntermediateNode) { - var generalStateName = node.functionCallName - .substring(0, node.functionCallName.lastIndexOf('/')); - - var globalVariableName = getVariableName(node.name.snakeCase); - managerData.addGlobalVariable(PBVariable(globalVariableName, 'var ', - true, '${generalStateName.pascalCase}Bloc()')); - - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - - managerData.addToDispose('$globalVariableName.close()'); - if (node.generator is! StringGeneratorAdapter) { - node.generator = StringGeneratorAdapter(''' - BlocBuilder<${generalStateName.pascalCase}Bloc, ${generalStateName.pascalCase}State>( - cubit: $globalVariableName, - builder: (context, state) => state.widget - ) - '''); - } - return handleNode(node); - } - var parentState = getNameOfNode(node); - var generalName = parentState.snakeCase; - var parentDirectory = generalName + '_bloc'; - var states = [node]; - - var stateBuffer = StringBuffer(); - - node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - states.add(state.variation.node); - }); - - var isFirst = true; - states.forEach((element) { - element.currentContext.tree.data = node.managerData; - element.generator.templateStrategy = BLoCStateTemplateStrategy( - isFirst: isFirst, - abstractClassName: parentState, - ); - stateBuffer.write(generationManager.generate(element)); - isFirst = false; - }); - - /// Creates state page - fileStrategy.commandCreated(WriteSymbolCommand( - - /// modified the [UUID] to prevent adding import because the state is - /// using `part of` syntax already when importing the bloc - 'STATE${node.currentContext.tree.UUID}', - '${generalName}_state', - stateBuffer.toString(), - relativePath: parentDirectory)); - - /// Creates event page - fileStrategy.commandCreated(WriteSymbolCommand( - - /// modified the [UUID] to prevent adding import because the event is - /// using `part of` syntax already when importing the bloc - 'EVENT${node.currentContext.tree.UUID}', - '${generalName}_event', - _createEventPage(parentState), - relativePath: parentDirectory)); - - /// Creates bloc page - managerData.addImport(FlutterImport('meta.dart', 'meta')); - fileStrategy.commandCreated(WriteSymbolCommand( - node.currentContext.tree.UUID, - '${generalName}_bloc', - _createBlocPage( - parentState, - node.name, - ), - relativePath: parentDirectory)); - - return handleNode(null); - } - return handleNode(node); - } - String _createBlocPage(String name, String initialStateName) { var pascalName = name.pascalCase; var snakeName = name.snakeCase; @@ -157,4 +67,91 @@ class BLoCMiddleware extends Middleware { '${getName(symbolMaster.name).snakeCase}_bloc', ); } + + @override + Future handleStatefulNode(PBIntermediateNode node) { + var managerData = node.managerData; + node.currentContext.project.genProjectData + .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); + managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); + var fileStrategy = node.currentContext.project.fileStructureStrategy + as FlutterFileStructureStrategy; + + /// Incase of SymbolInstance + if (node is PBSharedInstanceIntermediateNode) { + var generalStateName = node.functionCallName + .substring(0, node.functionCallName.lastIndexOf('/')); + + var globalVariableName = getVariableName(node.name.snakeCase); + managerData.addGlobalVariable(PBVariable(globalVariableName, 'var ', true, + '${generalStateName.pascalCase}Bloc()')); + + addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + + managerData.addToDispose('$globalVariableName.close()'); + if (node.generator is! StringGeneratorAdapter) { + node.generator = StringGeneratorAdapter(''' + BlocBuilder<${generalStateName.pascalCase}Bloc, ${generalStateName.pascalCase}State>( + cubit: $globalVariableName, + builder: (context, state) => state.widget + ) + '''); + } + return Future.value(node); + } + var parentState = getNameOfNode(node); + var generalName = parentState.snakeCase; + var parentDirectory = generalName + '_bloc'; + var states = [node]; + + var stateBuffer = StringBuffer(); + + node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + states.add(state.variation.node); + }); + + var isFirst = true; + states.forEach((element) { + element.currentContext.tree.data = node.managerData; + element.generator.templateStrategy = BLoCStateTemplateStrategy( + isFirst: isFirst, + abstractClassName: parentState, + ); + stateBuffer.write(generationManager.generate(element)); + isFirst = false; + }); + + /// Creates state page + fileStrategy.commandCreated(WriteSymbolCommand( + + /// modified the [UUID] to prevent adding import because the state is + /// using `part of` syntax already when importing the bloc + 'STATE${node.currentContext.tree.UUID}', + '${generalName}_state', + stateBuffer.toString(), + relativePath: parentDirectory)); + + /// Creates event page + fileStrategy.commandCreated(WriteSymbolCommand( + + /// modified the [UUID] to prevent adding import because the event is + /// using `part of` syntax already when importing the bloc + 'EVENT${node.currentContext.tree.UUID}', + '${generalName}_event', + _createEventPage(parentState), + relativePath: parentDirectory)); + + /// Creates bloc page + managerData.addImport(FlutterImport('meta.dart', 'meta')); + fileStrategy.commandCreated(WriteSymbolCommand( + node.currentContext.tree.UUID, + '${generalName}_bloc', + _createBlocPage( + parentState, + node.name, + ), + relativePath: parentDirectory)); + + return Future.value(null); + } } diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index cc82a8b4..4be1ccbf 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -1,6 +1,6 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; -import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; +import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; @@ -20,7 +20,7 @@ import 'package:path/path.dart' as p; import '../../pb_flutter_generator.dart'; -class ProviderMiddleware extends Middleware { +class ProviderMiddleware extends StateManagementMiddleware { final PACKAGE_NAME = 'provider'; final PACKAGE_VERSION = '^4.3.2+3'; @@ -28,36 +28,51 @@ class ProviderMiddleware extends Middleware { ProviderGenerationConfiguration configuration) : super(generationManager, configuration); + String getImportPath(PBSharedInstanceIntermediateNode node, + ProviderFileStructureStrategy fileStrategy, + {bool generateModelPath = true}) { + var symbolMaster = + PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); + + var import = generateModelPath + ? p.join(fileStrategy.RELATIVE_MODEL_PATH, + getName(symbolMaster.name).snakeCase) + : p.join( + FileStructureStrategy.RELATIVE_VIEW_PATH, + getName(symbolMaster.name).snakeCase, + node.functionCallName.snakeCase); + return p.join(fileStrategy.GENERATED_PROJECT_PATH, import); + } + @override - Future applyMiddleware(PBIntermediateNode node) async { - if (containsState(node) || containsMasterState(node)) { - String watcherName; - var managerData = node.managerData; - var fileStrategy = - configuration.fileStructureStrategy as ProviderFileStructureStrategy; - if (node is PBSharedInstanceIntermediateNode) { - node.currentContext.project.genProjectData - .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport(FlutterImport('provider.dart', 'provider')); - watcherName = getVariableName(node.name.snakeCase + '_notifier'); - var widgetName = node.functionCallName.camelCase; - var watcher; - - if (node.currentContext.tree.rootNode.generator.templateStrategy - is StatelessTemplateStrategy) { - watcher = PBVariable(watcherName, 'final ', true, - '${getName(node.functionCallName).pascalCase}().$widgetName'); - managerData.addGlobalVariable(watcher); - } - - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - PBGenCache().appendToCache(node.SYMBOL_ID, - getImportPath(node, fileStrategy, generateModelPath: false)); - - if (node.generator is! StringGeneratorAdapter) { - var modelName = getName(node.functionCallName).pascalCase; - var defaultWidget = node.functionCallName.pascalCase; - var providerWidget = ''' + Future handleStatefulNode(PBIntermediateNode node) { + String watcherName; + var managerData = node.managerData; + var fileStrategy = + configuration.fileStructureStrategy as ProviderFileStructureStrategy; + if (node is PBSharedInstanceIntermediateNode) { + node.currentContext.project.genProjectData + .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); + managerData.addImport(FlutterImport('provider.dart', 'provider')); + watcherName = getVariableName(node.name.snakeCase + '_notifier'); + var widgetName = node.functionCallName.camelCase; + var watcher; + + if (node.currentContext.tree.rootNode.generator.templateStrategy + is StatelessTemplateStrategy) { + watcher = PBVariable(watcherName, 'final ', true, + '${getName(node.functionCallName).pascalCase}().$widgetName'); + managerData.addGlobalVariable(watcher); + } + + addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + PBGenCache().appendToCache(node.SYMBOL_ID, + getImportPath(node, fileStrategy, generateModelPath: false)); + + if (node.generator is! StringGeneratorAdapter) { + var modelName = getName(node.functionCallName).pascalCase; + var defaultWidget = node.functionCallName.pascalCase; + var providerWidget = ''' ChangeNotifierProvider( create: (context) => $modelName(), @@ -81,69 +96,51 @@ class ProviderMiddleware extends Middleware { ), ) '''; - node.generator = StringGeneratorAdapter(providerWidget); - } - - return handleNode(node); + node.generator = StringGeneratorAdapter(providerWidget); } - watcherName = getNameOfNode(node); - - var parentDirectory = getName(node.name).snakeCase; - - // Generate model's imports - var modelGenerator = PBFlutterGenerator(ImportHelper(), - data: PBGenerationViewData() - ..addImport(FlutterImport('material.dart', 'flutter'))); - // Write model class for current node - var code = MiddlewareUtils.generateModelChangeNotifier( - watcherName, modelGenerator, node); - - [ - /// This generated the `changeNotifier` that goes under the [fileStrategy.RELATIVE_MODEL_PATH] - WriteSymbolCommand( - node.currentContext.tree.UUID, - parentDirectory, - code, - symbolPath: fileStrategy.RELATIVE_MODEL_PATH, - ), - // Generate default node's view page - WriteSymbolCommand(node.currentContext.tree.UUID, node.name.snakeCase, - generationManager.generate(node), - relativePath: parentDirectory), - ].forEach(fileStrategy.commandCreated); - - (configuration as ProviderGenerationConfiguration) - .registeredModels - .add(watcherName); - - // Generate node's states' view pages - node.auxiliaryData?.stateGraph?.states?.forEach((state) { - fileStrategy.commandCreated(WriteSymbolCommand( - state.variation.node.currentContext.tree.UUID, - state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node), - relativePath: parentDirectory, - )); - }); - - return handleNode(null); - } - return handleNode(node); - } - - String getImportPath(PBSharedInstanceIntermediateNode node, - ProviderFileStructureStrategy fileStrategy, - {bool generateModelPath = true}) { - var symbolMaster = - PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); - var import = generateModelPath - ? p.join(fileStrategy.RELATIVE_MODEL_PATH, - getName(symbolMaster.name).snakeCase) - : p.join( - FileStructureStrategy.RELATIVE_VIEW_PATH, - getName(symbolMaster.name).snakeCase, - node.functionCallName.snakeCase); - return p.join(fileStrategy.GENERATED_PROJECT_PATH, import); + return Future.value(node); + } + watcherName = getNameOfNode(node); + + var parentDirectory = getName(node.name).snakeCase; + + // Generate model's imports + var modelGenerator = PBFlutterGenerator(ImportHelper(), + data: PBGenerationViewData() + ..addImport(FlutterImport('material.dart', 'flutter'))); + // Write model class for current node + var code = MiddlewareUtils.generateModelChangeNotifier( + watcherName, modelGenerator, node); + + [ + /// This generated the `changeNotifier` that goes under the [fileStrategy.RELATIVE_MODEL_PATH] + WriteSymbolCommand( + node.currentContext.tree.UUID, + parentDirectory, + code, + symbolPath: fileStrategy.RELATIVE_MODEL_PATH, + ), + // Generate default node's view page + WriteSymbolCommand(node.currentContext.tree.UUID, node.name.snakeCase, + generationManager.generate(node), + relativePath: parentDirectory), + ].forEach(fileStrategy.commandCreated); + + (configuration as ProviderGenerationConfiguration) + .registeredModels + .add(watcherName); + + // Generate node's states' view pages + node.auxiliaryData?.stateGraph?.states?.forEach((state) { + fileStrategy.commandCreated(WriteSymbolCommand( + state.variation.node.currentContext.tree.UUID, + state.variation.node.name.snakeCase, + generationManager.generate(state.variation.node), + relativePath: parentDirectory, + )); + }); + + return Future.value(null); } } diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 599c1b9b..26c76092 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/generation/generators/import_generator.dart'; +import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; @@ -10,10 +11,9 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import '../../pb_generation_manager.dart'; import '../../pb_variable.dart'; -import '../middleware.dart'; import 'package:recase/recase.dart'; -class RiverpodMiddleware extends Middleware { +class RiverpodMiddleware extends StateManagementMiddleware { final PACKAGE_NAME = 'flutter_riverpod'; final PACKAGE_VERSION = '^0.12.1'; @@ -21,53 +21,6 @@ class RiverpodMiddleware extends Middleware { RiverpodGenerationConfiguration configuration) : super(generationManager, configuration); - @override - Future applyMiddleware(PBIntermediateNode node) async { - if (containsState(node) || containsMasterState(node)) { - String watcherName; - var managerData = node.managerData; - var fileStrategy = - configuration.fileStructureStrategy as RiverpodFileStructureStrategy; - - if (node is PBSharedInstanceIntermediateNode) { - node.currentContext.project.genProjectData - .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport( - FlutterImport('flutter_riverpod.dart', 'flutter_riverpod')); - watcherName = getVariableName(node.functionCallName.snakeCase); - var watcher = PBVariable(watcherName + '_provider', 'final ', true, - 'ChangeNotifierProvider((ref) => ${getName(node.functionCallName).pascalCase}())'); - - if (node.currentContext.tree.rootNode.generator.templateStrategy - is StatelessTemplateStrategy) { - managerData.addGlobalVariable(watcher); - } else { - managerData.addMethodVariable(watcher); - } - - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - - if (node.generator is! StringGeneratorAdapter) { - node.generator = StringGeneratorAdapter( - getConsumer(watcherName, node.functionCallName.camelCase)); - } - return handleNode(node); - } - watcherName = getNameOfNode(node); - - var code = MiddlewareUtils.generateChangeNotifierClass( - watcherName, - generationManager, - node, - ); - fileStrategy.commandCreated(WriteSymbolCommand( - node.currentContext.tree.UUID, getName(node.name).snakeCase, code, - symbolPath: fileStrategy.RELATIVE_MODEL_PATH)); - } - - return handleNode(node); - } - String getConsumer(String name, String pointTo) { return ''' Consumer( @@ -86,4 +39,48 @@ class RiverpodMiddleware extends Middleware { fileStrategy.RELATIVE_MODEL_PATH + '${getName(symbolMaster.name).snakeCase}.dart'; } + + @override + Future handleStatefulNode(PBIntermediateNode node) { + String watcherName; + var managerData = node.managerData; + var fileStrategy = + configuration.fileStructureStrategy as RiverpodFileStructureStrategy; + + if (node is PBSharedInstanceIntermediateNode) { + node.currentContext.project.genProjectData + .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); + managerData.addImport( + FlutterImport('flutter_riverpod.dart', 'flutter_riverpod')); + watcherName = getVariableName(node.functionCallName.snakeCase); + var watcher = PBVariable(watcherName + '_provider', 'final ', true, + 'ChangeNotifierProvider((ref) => ${getName(node.functionCallName).pascalCase}())'); + + if (node.currentContext.tree.rootNode.generator.templateStrategy + is StatelessTemplateStrategy) { + managerData.addGlobalVariable(watcher); + } else { + managerData.addMethodVariable(watcher); + } + + addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + + if (node.generator is! StringGeneratorAdapter) { + node.generator = StringGeneratorAdapter( + getConsumer(watcherName, node.functionCallName.camelCase)); + } + return Future.value(node); + } + watcherName = getNameOfNode(node); + + var code = MiddlewareUtils.generateChangeNotifierClass( + watcherName, + generationManager, + node, + ); + fileStrategy.commandCreated(WriteSymbolCommand( + node.currentContext.tree.UUID, getName(node.name).snakeCase, code, + symbolPath: fileStrategy.RELATIVE_MODEL_PATH)); + return Future.value(null); + } } diff --git a/lib/generation/generators/middleware/state_management/state_management_middleware.dart b/lib/generation/generators/middleware/state_management/state_management_middleware.dart new file mode 100644 index 00000000..1400341b --- /dev/null +++ b/lib/generation/generators/middleware/state_management/state_management_middleware.dart @@ -0,0 +1,61 @@ +import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; +import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; + +/// This [Middleware] is going to focus on the [PBIntermediateNode]s that +/// satisfy either [containsMasterState] or simply [containsState]. +/// +/// Unlike the regular [Middleware] were they are able to handle the entire +/// [PBIntermediateTree], the [StateManagementMiddleware] is going to handle each +/// individual [PBIntermediateNode]. +abstract class StateManagementMiddleware extends Middleware { + StateManagementMiddleware(PBGenerationManager generationManager, + GenerationConfiguration configuration) + : super(generationManager, configuration); + + /// Forwards all of the nodes of the tree to the [handleStatefulNode], + /// the method overridden by the [StateManagementMiddleware]. + /// + /// Since the [StateManagementMiddleware] is meant to process all the + /// stateful [PBIntermediateNode] within a [tree], it has to traverse all the [tree] [PBIntermediateNode]s. + /// To accomplish this, the [StateManagementMiddleware] will forward all + /// the [tree] nodes to the [handleStatefulNode] method. Once all the nodes have + /// been processed, we will assign the [PBIntermediateTree.rootNode] back to the [tree] and return the [tree]. + /// The last thing to note here is if the [PBIntermediateTree.rootNode] happens to be null, + /// in which case the tree will return `null`; no other [Middleware] will be applied to the [tree], + /// making the final result `null`. + @override + Future applyMiddleware(PBIntermediateTree tree) { + return Future.wait(tree.map((node) { + if (containsState(node) || containsMasterState(node)) { + return handleStatefulNode(node); + } + return Future.value(node); + })).then((nodes) { + tree.rootNode = nodes.first; + return handleTree(tree.rootNode == null ? null : tree); + }); + } + + /// Handles the nodes that are stateful(either [containsState] or [containsMasterState]). + Future handleStatefulNode(PBIntermediateNode node); + + /// Checks whether the master of the [PBSharedInstanceIntermediateNode] (if the [node] + /// is a symbol) [containsState]. + bool containsMasterState(PBIntermediateNode node) { + if (node is PBSharedInstanceIntermediateNode) { + return node.isMasterState || + containsState( + PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID)); + } + return false; + } + + /// Checks wheather the [node] contains any states. + bool containsState(PBIntermediateNode node) => + node?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false; +} diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index c459b439..81f52c36 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -1,4 +1,4 @@ -import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; +import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -9,37 +9,11 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.d import 'package:recase/recase.dart'; import 'package:path/path.dart' as p; -class StatefulMiddleware extends Middleware { +class StatefulMiddleware extends StateManagementMiddleware { StatefulMiddleware(PBGenerationManager generationManager, GenerationConfiguration configuration) : super(generationManager, configuration); - @override - Future applyMiddleware(PBIntermediateNode node) async { - if (containsState(node) || containsMasterState(node)) { - var fileStrategy = configuration.fileStructureStrategy; - - if (node is PBSharedInstanceIntermediateNode) { - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - return handleNode(node); - } - var parentDirectory = getName(node.name).snakeCase; - - fileStrategy.commandCreated(WriteSymbolCommand( - node.UUID, parentDirectory, generationManager.generate(node))); - - node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - state.variation.node.currentContext.tree.data = node.managerData; - fileStrategy.commandCreated(WriteSymbolCommand( - state.variation.node.currentContext.tree.UUID, - state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node))); - }); - } - - return handleNode(node); - } - String getImportPath(PBSharedInstanceIntermediateNode node, FileStructureStrategy fileStrategy) { var symbolMaster = @@ -51,4 +25,27 @@ class StatefulMiddleware extends Middleware { node.functionCallName.snakeCase); return path; } + + @override + Future handleStatefulNode(PBIntermediateNode node) { + var fileStrategy = configuration.fileStructureStrategy; + + if (node is PBSharedInstanceIntermediateNode) { + addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + return Future.value(node); + } + var parentDirectory = getName(node.name).snakeCase; + + fileStrategy.commandCreated(WriteSymbolCommand( + node.UUID, parentDirectory, generationManager.generate(node))); + + node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + state.variation.node.currentContext.tree.data = node.managerData; + fileStrategy.commandCreated(WriteSymbolCommand( + state.variation.node.currentContext.tree.UUID, + state.variation.node.name.snakeCase, + generationManager.generate(state.variation.node))); + }); + return Future.value(null); + } } diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index ad2cb52d..f929bff4 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -41,7 +41,7 @@ class MiddlewareUtils { stateInitializers.write( '${variationNode.name.camelCase} = ${MiddlewareUtils.generateVariableBody(variationNode)}'); } else { - stateBuffer.write(MiddlewareUtils.generateVariable(variationNode)); + stateBuffer.writeln(MiddlewareUtils.generateVariable(variationNode)); } }); @@ -87,7 +87,7 @@ class MiddlewareUtils { static String generateVariable(PBIntermediateNode node, {String type = 'var'}) { - return '$type ${node.name.camelCase} = ${generateVariableBody(node)}'; + return '$type ${node.name.camelCase} = ${generateVariableBody(node)};'; } static String generateEmptyVariable(PBIntermediateNode node, diff --git a/lib/generation/generators/util/stateful_nodes_mixin.dart b/lib/generation/generators/util/stateful_nodes_mixin.dart deleted file mode 100644 index 073b16cc..00000000 --- a/lib/generation/generators/util/stateful_nodes_mixin.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; - -mixin StatefulNodeMixin { - bool containsMasterState(PBIntermediateNode node) { - if (node is PBSharedInstanceIntermediateNode) { - return node.isMasterState || - containsState( - PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID)); - } - return false; - } - - bool containsState(PBIntermediateNode node) => - node?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false; -} diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index ae19cfb3..71ecd7ae 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,28 +1,23 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; +import 'package:parabeac_core/generation/generators/middleware/command_gen_middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/command_invoker.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:quick_log/quick_log.dart'; @@ -74,27 +69,24 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } ///This is going to modify the [PBIntermediateNode] in order to affect the structural patterns or file structure produced. - Future applyMiddleware(PBIntermediateNode node) async { - node = await _head.applyMiddleware(node); - - return node; - } - - ///Applying the registered [Middleware] to all the [PBIntermediateNode]s within the [PBIntermediateTree] - Future _applyMiddleware(PBIntermediateTree tree) async { - tree.rootNode = - (await Future.wait(tree.map(applyMiddleware).toList())).first; - - return tree.rootNode == null ? null : tree; - } + Future applyMiddleware(PBIntermediateTree tree) => + _head.applyMiddleware(tree); + /// It is generating the [List] of [trees] by passing them through the link list + /// of [Middleware]. + /// + /// Before passing through the [Middleware], + /// each of the [PBIntermediateTree] is going to be analyzed by the [poLinker]. + /// The result should be the segregation of platforms and their orientation. + /// Finally, if the [PBIntermediateTree.isHomeScreen], it will modify the main file to + /// reflect that information. At the end, the [Middleware] should be executing [FileStructureCommands] + /// that generate the code for each tree in the [trees]. Future generateTrees( List trees, PBProject project) async { for (var tree in trees) { tree.rootNode.currentContext.generationManager = generationManager; - - tree.data.addImport(FlutterImport('material.dart', 'flutter')); generationManager.data = tree.data; + tree.data.addImport(FlutterImport('material.dart', 'flutter')); // Relative path to the file to create var relPath = p.join(tree.name.snakeCase, tree.identifier); @@ -108,16 +100,15 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { if (tree.isHomeScreen()) { await _setMainScreen(tree, relPath, project.projectName); } - tree = await _applyMiddleware(tree); - if (tree == null) { - continue; - } - fileStructureStrategy.commandCreated(_createCommand(tree, project)); + await applyMiddleware(tree); } } ///Generates the [PBIntermediateTree]s within the [pb_project] Future generateProject(PBProject pb_project) async { + _head = CommandGenMiddleware( + generationManager, this, _importProcessor, pb_project.projectName); + ///First we are going to perform a dry run in the generation to ///gather all the necessary information await setUpConfiguration(pb_project); @@ -141,59 +132,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await _commitDependencies(pb_project.projectAbsPath); } - FileStructureCommand _createCommand( - PBIntermediateTree tree, PBProject project) { - var command; - _addDependencyImports(tree, project.projectName); - if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { - getPlatformOrientationName(tree.rootNode); - - command = ExportPlatformCommand( - tree.UUID, - tree.rootNode.currentContext.tree.data.platform, - tree.identifier, - tree.rootNode.name.snakeCase, - generationManager.generate(tree.rootNode), - ); - } else if (tree.isScreen()) { - command = WriteScreenCommand( - tree.UUID, - tree.identifier, - tree.name.snakeCase, - generationManager.generate(tree.rootNode), - ); - } else { - var relativePath = tree.name.snakeCase; //symbols - - command = WriteSymbolCommand( - tree.UUID, - tree.identifier, - generationManager.generate(tree.rootNode), - relativePath: relativePath, - ); - } - - return command; - } - - /// Method that traverses `tree`'s dependencies and looks for an import path from - /// [ImportHelper]. - /// - /// If an import path is found, it will be added to the `tree`'s data. The package format - /// for imports is going to be enforced, therefore, [packageName] is going to be - /// a required parameter. - void _addDependencyImports(PBIntermediateTree tree, String packageName) { - var iter = tree.dependentsOn; - var addImport = tree.rootNode.managerData.addImport; - - while (iter.moveNext()) { - _importProcessor.getFormattedImports( - iter.current.UUID, - importMapper: (import) => addImport(FlutterImport(import, packageName)), - ); - } - } - void registerMiddleware(Middleware middleware) { if (middleware != null) { if (_head == null) { @@ -201,8 +139,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } else { middleware.nextMiddleware = _head; _head = middleware; - - middleware.generationManager = generationManager; } } } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index d60ea7b0..19820d43 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -42,7 +42,7 @@ class PBIntermediateTree extends Iterable { set rootNode(PBIntermediateNode rootNode) { if (!lockData) { _rootNode = rootNode; - _identifier ??= rootNode?.name ?? name; + _identifier ??= rootNode?.name?.snakeCase ?? name.snakeCase; if (rootNode is InheritedScaffold) { _tree_type = TREE_TYPE.SCREEN; @@ -62,7 +62,7 @@ class PBIntermediateTree extends Iterable { /// The [name] of the original [DesignPage] that the [PBIntermediateTree] belongs to. String _name; - String get name => _name; + String get name => _name.snakeCase; set name(String name) { if (!lockData) { _name = name; From 2db1ad334b82e6a222dc550129667b350c68e92c Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 3 Jun 2021 19:25:03 -0600 Subject: [PATCH 181/404] Use `path.join()` for reference to pngs directory --- lib/design_logic/boolean_operation.dart | 7 ++++--- lib/design_logic/image.dart | 17 ++++++++--------- lib/design_logic/vector.dart | 7 ++++--- .../flutter_project_builder.dart | 3 ++- .../figma/helper/figma_asset_processor.dart | 8 ++++---- lib/input/sketch/services/input_design.dart | 6 ++++-- .../helpers/pb_image_reference_storage.dart | 5 +++-- lib/main.dart | 7 +++---- test/lib/output_services/png_gen_test.dart | 4 +++- 9 files changed, 35 insertions(+), 29 deletions(-) diff --git a/lib/design_logic/boolean_operation.dart b/lib/design_logic/boolean_operation.dart index 9edbcc8f..8b03cc13 100644 --- a/lib/design_logic/boolean_operation.dart +++ b/lib/design_logic/boolean_operation.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:path/path.dart' as p; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -32,9 +33,9 @@ class BooleanOperation implements DesignNodeFactory, DesignNode { @override Future interpretNode(PBContext currentContext) async { var img = await AzureAssetService().downloadImage(UUID); - var file = - File('${MainInfo().outputPath}pngs/$UUID.png'.replaceAll(':', '_')) - ..createSync(recursive: true); + var path = + p.join(MainInfo().outputPath, 'pngs', '$UUID.png'.replaceAll(':', '_')); + var file = File(path)..createSync(recursive: true); file.writeAsBytesSync(img); return Future.value(InheritedBitmap( diff --git a/lib/design_logic/image.dart b/lib/design_logic/image.dart index 87fca40f..d6d1d5a5 100644 --- a/lib/design_logic/image.dart +++ b/lib/design_logic/image.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:path/path.dart' as p; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_element.dart'; @@ -93,11 +94,11 @@ class Image extends DesignElement implements DesignNodeFactory, DesignNode { @override Future interpretNode(PBContext currentContext) async { + var pngsPath = + p.join(MainInfo().outputPath, 'pngs', '$UUID.png'.replaceAll(':', '_')); try { var img = await AzureAssetService().downloadImage(UUID); - var file = - File('${MainInfo().outputPath}pngs/$UUID.png'.replaceAll(':', '_')) - ..createSync(recursive: true); + var file = File(pngsPath)..createSync(recursive: true); file.writeAsBytesSync(img); return Future.value(InheritedBitmap( this, @@ -105,12 +106,10 @@ class Image extends DesignElement implements DesignNodeFactory, DesignNode { currentContext: currentContext, )); } catch (e) { - var img = File( - '${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png') - .readAsBytesSync(); - var file = - File('${MainInfo().outputPath}pngs/$UUID.png'.replaceAll(':', '_')) - ..createSync(recursive: true); + var errPath = p.join(MainInfo().cwd?.path, 'lib', 'input', 'assets', + 'image-conversion-error.png'); + var img = File(errPath).readAsBytesSync(); + var file = File(pngsPath)..createSync(recursive: true); file.writeAsBytesSync(img); return Future.value(InheritedBitmap( this, diff --git a/lib/design_logic/vector.dart b/lib/design_logic/vector.dart index e19e0755..14d537a8 100644 --- a/lib/design_logic/vector.dart +++ b/lib/design_logic/vector.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:path/path.dart' as p; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -106,9 +107,9 @@ class Vector implements DesignNodeFactory, DesignNode, Image { imageReference = AssetProcessingService.getImageName(UUID); - var file = - File('${MainInfo().outputPath}pngs/$UUID.png'.replaceAll(':', '_')) - ..createSync(recursive: true); + var pngsPath = + p.join(MainInfo().outputPath, 'pngs', '$UUID.png'.replaceAll(':', '_')); + var file = File(pngsPath)..createSync(recursive: true); file.writeAsBytesSync(img); return Future.value( InheritedBitmap(this, name, currentContext: currentContext)); diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index f130a6b6..a125b566 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -70,10 +70,11 @@ class FlutterProjectBuilder { await FigmaAssetProcessor().processImageQueue(); } + var pngsPath = p.join(MainInfo().outputPath, 'pngs', '*'); Process.runSync( '${MainInfo().cwd.path}/lib/generation/helperScripts/shell-proxy.sh', [ - 'mv ${MainInfo().outputPath}/pngs/* ${pathToFlutterProject}assets/images/' + 'mv $pngsPath ${pathToFlutterProject}assets/images/' ], runInShell: true, environment: Platform.environment, diff --git a/lib/input/figma/helper/figma_asset_processor.dart b/lib/input/figma/helper/figma_asset_processor.dart index b600be8b..83a17363 100644 --- a/lib/input/figma/helper/figma_asset_processor.dart +++ b/lib/input/figma/helper/figma_asset_processor.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:path/path.dart' as p; import 'package:http/http.dart' as http; import 'package:parabeac_core/controllers/main_info.dart'; @@ -85,10 +86,9 @@ class FigmaAssetProcessor extends AssetProcessingService { } if (writeAsFile) { - var file = File( - '${MainInfo().outputPath}pngs/${entry.key}.png' - .replaceAll(':', '_')) - ..createSync(recursive: true); + var pngsPath = p.join(MainInfo().outputPath, 'pngs', + '${entry.key}.png'.replaceAll(':', '_')); + var file = File(pngsPath)..createSync(recursive: true); file.writeAsBytesSync(imageRes.bodyBytes); } else { await super.uploadToStorage(imageRes.bodyBytes, entry.key); diff --git a/lib/input/sketch/services/input_design.dart b/lib/input/sketch/services/input_design.dart index 43e6e33c..bb315e46 100644 --- a/lib/input/sketch/services/input_design.dart +++ b/lib/input/sketch/services/input_design.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_page.dart'; import 'package:path/path.dart'; import 'package:archive/archive.dart'; +import 'package:path/path.dart' as p; /// Takes Initial Design File and puts it into a tree in object format. /// Currently only supports Sketch Files @@ -43,13 +44,14 @@ class InputDesignService { ///Getting the images in the sketch file and adding them to the png folder. void setImageDir() { ///Creating the pngs folder, if it's already not there. - Directory('${MainInfo().outputPath}pngs').createSync(recursive: true); + var pngsPath = p.join(MainInfo().outputPath, 'pngs'); + Directory(pngsPath).createSync(recursive: true); for (final file in archive) { final fileName = file.name; if (file.isFile && fileName.contains(IMAGE_DIR_NAME)) { final data = file.content as List; final name = fileName.replaceAll(IMAGE_DIR_NAME, ''); - File('${MainInfo().outputPath}pngs/$name').writeAsBytesSync(data); + File(p.join(pngsPath, name)).writeAsBytesSync(data); } } } diff --git a/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart b/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart index 233388d8..178d9d69 100644 --- a/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart +++ b/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'dart:typed_data'; +import 'package:path/path.dart' as p; import 'package:parabeac_core/controllers/main_info.dart'; @@ -24,17 +25,17 @@ class ImageReferenceStorage { /// Adds the reference to the image and writes the png to the assets folder. /// Returns true if the image was written successfully, false otherwise bool addReferenceAndWrite(String name, String path, Uint8List image) { + var imgPath = p.join(MainInfo().outputPath, 'pngs', '$name.png'); if (image == null && File('${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png') .existsSync() && addReference(name, '${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png')) { File('${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png') - .copySync('${MainInfo().outputPath}pngs/$name.png'); + .copySync(imgPath); return true; } if (addReference(name, path)) { - var imgPath = '${MainInfo().outputPath}pngs/$name.png'; if (!File(imgPath).existsSync()) { File(imgPath).createSync(recursive: true); } diff --git a/lib/main.dart b/lib/main.dart index b1df5bee..fffc4a7b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -130,10 +130,9 @@ ${parser.usage} MainInfo().configuration = configuration; // Create pngs directory - - await Directory('${MainInfo().outputPath}' + - (jsonOnly || argResults['pbdl-in'] != null ? '' : 'pngs')) - .create(recursive: true); + var pngsPath = p.join(MainInfo().outputPath, + (jsonOnly || argResults['pbdl-in'] != null ? '' : 'pngs')); + await Directory(pngsPath).create(recursive: true); if (designType == 'sketch') { if (argResults['pbdl-in'] != null) { diff --git a/test/lib/output_services/png_gen_test.dart b/test/lib/output_services/png_gen_test.dart index be0be362..a1a25fcf 100644 --- a/test/lib/output_services/png_gen_test.dart +++ b/test/lib/output_services/png_gen_test.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:io'; +import 'package:path/path.dart' as p; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; @@ -93,7 +94,8 @@ void main() async { await FigmaAssetProcessor().processImageQueue(); for (var uuid in FigmaAssetProcessor().uuidQueue) { expect( - File('${MainInfo().outputPath}pngs/$uuid.png'.replaceAll(':', '_')) + File(p.join(MainInfo().outputPath, 'pngs', + '$uuid.png'.replaceAll(':', '_'))) .existsSync(), true); } From 2f4df3d1203e47b84187b26c0162953692b4b861 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Fri, 4 Jun 2021 16:47:41 -0600 Subject: [PATCH 182/404] Fix syntax errors on testing files --- lib/controllers/interpret.dart | 2 +- test/lib/controllers/interpret_test.dart | 3 ++- .../services/interpret_test.dart | 5 ++++- test/lib/middleware/bloc_test.dart | 11 +++++++---- test/lib/middleware/provider_test.dart | 9 ++++++--- test/lib/middleware/stateful_test.dart | 12 +++++++----- test/lib/output_services/project_builder_test.dart | 10 +++++----- 7 files changed, 32 insertions(+), 20 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 0df68a89..319b14f8 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -41,7 +41,7 @@ class Interpret { PBPrototypeLinkerService _pbPrototypeLinkerService; PBConfiguration configuration; - void init(String projectName, configuration) { + void init(String projectName, PBConfiguration configuration) { this.configuration ??= configuration; log = Logger(runtimeType.toString()); _interpret._pbSymbolLinkerService = PBSymbolLinkerService(); diff --git a/test/lib/controllers/interpret_test.dart b/test/lib/controllers/interpret_test.dart index dc42972f..3f257069 100644 --- a/test/lib/controllers/interpret_test.dart +++ b/test/lib/controllers/interpret_test.dart @@ -1,6 +1,7 @@ import 'package:mockito/mockito.dart'; import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_project.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:test/test.dart'; class MockSketchProject extends Mock implements SketchProject {} @@ -10,7 +11,7 @@ void main() { test('Interpret should instantiate', () { var nameOfProject = 'test Project'; interpret = Interpret(); - interpret.init(nameOfProject); + interpret.init(nameOfProject, PBConfiguration.genericConfiguration()); expect(interpret, isNotNull); expect(interpret.projectName, nameOfProject); }); diff --git a/test/lib/interpret_and_optimize/services/interpret_test.dart b/test/lib/interpret_and_optimize/services/interpret_test.dart index eb8a0f98..b3293f4d 100644 --- a/test/lib/interpret_and_optimize/services/interpret_test.dart +++ b/test/lib/interpret_and_optimize/services/interpret_test.dart @@ -13,6 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_containe import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -71,7 +72,9 @@ void main() { group('Interpret test', () { setUp(() { Interpret().init( - '${Directory.current.path}/test/lib/interpret_and_optimize/services'); + '${Directory.current.path}/test/lib/interpret_and_optimize/services', + PBConfiguration.genericConfiguration(), + ); MainInfo().configurationType = 'default'; diff --git a/test/lib/middleware/bloc_test.dart b/test/lib/middleware/bloc_test.dart index 3cf1af72..cc3fa7b5 100644 --- a/test/lib/middleware/bloc_test.dart +++ b/test/lib/middleware/bloc_test.dart @@ -7,6 +7,8 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -34,9 +36,10 @@ class MockPBGenerator extends Mock implements PBGenerator {} void main() { group('Middlewares Tests', () { + var genConfig = BLoCGenerationConfiguration(); var testingPath = '${Directory.current.path}/test/lib/middleware/'; var mockPBGenerationManager = MockPBGenerationManager(); - var bLoCMiddleware = BLoCMiddleware(mockPBGenerationManager); + var bLoCMiddleware = BLoCMiddleware(mockPBGenerationManager, genConfig); var node = MockPBIntermediateNode(); var node2 = MockPBIntermediateNode(); var mockContext = MockContext(); @@ -88,7 +91,7 @@ void main() { /// Project when(mockProject.genProjectData).thenReturn(mockPBGenerationProjectData); when(mockProject.forest).thenReturn([]); - when(mockProject.fileStructureStrategy) + when(genConfig.fileStructureStrategy) .thenReturn(mockFileStructureStrategy); /// PBGenerationManager @@ -102,9 +105,9 @@ void main() { }); test('BLoC Strategy Test', () async { - var relativeViewPath = mockFileStructureStrategy.RELATIVE_VIEW_PATH; + var relativeViewPath = FileStructureStrategy.RELATIVE_VIEW_PATH; await mockFileStructureStrategy.setUpDirectories(); - var tempNode = await bLoCMiddleware.applyMiddleware(node); + var tempNode = await bLoCMiddleware.applyMiddleware(mockTree); expect(tempNode is PBIntermediateNode, true); expect( await File( diff --git a/test/lib/middleware/provider_test.dart b/test/lib/middleware/provider_test.dart index bd9da809..b3cad85f 100644 --- a/test/lib/middleware/provider_test.dart +++ b/test/lib/middleware/provider_test.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -45,9 +46,11 @@ class MockTree extends Mock implements PBIntermediateTree {} void main() { group('Middlewares Tests', () { + var config = ProviderGenerationConfiguration(); var testingPath = '${Directory.current.path}/test/lib/middleware/'; var mockPBGenerationManager = MockPBGenerationManager(); - var providerMiddleware = ProviderMiddleware(mockPBGenerationManager); + var providerMiddleware = + ProviderMiddleware(mockPBGenerationManager, config); var node = MockPBIntermediateNode(); var node2 = MockPBIntermediateNode(); var mockContext = MockContext(); @@ -103,7 +106,7 @@ void main() { /// Project when(mockProject.genProjectData).thenReturn(mockPBGenerationProjectData); when(mockProject.forest).thenReturn([]); - when(mockProject.fileStructureStrategy) + when(config.fileStructureStrategy) .thenReturn(providerFileStructureStrategy); /// PBGenerationManager @@ -115,7 +118,7 @@ void main() { test('Provider Strategy Test', () async { await providerFileStructureStrategy.setUpDirectories(); - var tempNode = await providerMiddleware.applyMiddleware(node); + var tempNode = await providerMiddleware.applyMiddleware(mockTree); expect(tempNode is PBIntermediateNode, true); expect(await File('${testingPath}lib/models/some_element.dart').exists(), true); diff --git a/test/lib/middleware/stateful_test.dart b/test/lib/middleware/stateful_test.dart index 130d1a8f..3910a676 100644 --- a/test/lib/middleware/stateful_test.dart +++ b/test/lib/middleware/stateful_test.dart @@ -7,6 +7,8 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -34,9 +36,10 @@ class MockTree extends Mock implements PBIntermediateTree {} void main() { group('Middlewares Tests', () { + var config = StatefulGenerationConfiguration(); var testingPath = '${Directory.current.path}/test/lib/middleware/'; var mockPBGenerationManager = MockPBGenerationManager(); - var bLoCMiddleware = StatefulMiddleware(mockPBGenerationManager); + var bLoCMiddleware = StatefulMiddleware(mockPBGenerationManager, config); var node = MockPBIntermediateNode(); var node2 = MockPBIntermediateNode(); var mockContext = MockContext(); @@ -88,8 +91,7 @@ void main() { /// Project when(mockProject.genProjectData).thenReturn(mockPBGenerationProjectData); when(mockProject.forest).thenReturn([]); - when(mockProject.fileStructureStrategy) - .thenReturn(mockFileStructureStrategy); + when(config.fileStructureStrategy).thenReturn(mockFileStructureStrategy); /// PBGenerationManager when(mockPBGenerationManager.generate(node)).thenReturn('codeForBlue\n'); @@ -102,9 +104,9 @@ void main() { }); test('Stateful Strategy Test', () async { - var relativeViewPath = mockFileStructureStrategy.RELATIVE_VIEW_PATH; + var relativeViewPath = FileStructureStrategy.RELATIVE_VIEW_PATH; await mockFileStructureStrategy.setUpDirectories(); - var tempNode = await bLoCMiddleware.applyMiddleware(node); + var tempNode = await bLoCMiddleware.applyMiddleware(mockTree); expect(tempNode is PBIntermediateNode, true); expect( await File( diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index b27cd32b..5f18ef1b 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_project_d import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; @@ -55,6 +56,7 @@ void main() { MockContext context; setUp(() async { + var config = StatefulGenerationConfiguration(); MainInfo().cwd = Directory.current; MainInfo().outputPath = '${Directory.current.path}/test/lib/output_services/'; @@ -69,12 +71,10 @@ void main() { containerGenerator = PBContainerGenerator(); scaffoldGenerator = PBScaffoldGenerator(); - MainInfo().configurations = {'state-management': 'none'}; - when(intermediateTree.rootNode).thenReturn(scaffold); when(intermediateTree.name).thenReturn('testTree'); when(intermediateTree.data).thenReturn(PBGenerationViewData()); - when(intermediateTree.dependentOn) + when(intermediateTree.dependentsOn) .thenReturn([].iterator); when(project.projectName).thenReturn( @@ -101,9 +101,9 @@ void main() { fss = FlutterFileStructureStrategy(outputPath, PBFlutterWriter(), project); await fss.setUpDirectories(); - when(project.fileStructureStrategy).thenReturn(fss); + when(config.fileStructureStrategy).thenReturn(fss); - projectBuilder = FlutterProjectBuilder( + projectBuilder = FlutterProjectBuilder(config, project: project, pageWriter: PBFlutterWriter()); }); test( From dae35a0ce7383d53f0f7b1df760f1b2299e76142 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Fri, 4 Jun 2021 17:12:07 -0600 Subject: [PATCH 183/404] Fix import bugs relating to incorrect UUID being passed to WriteSymbolCommand --- .../middleware/state_management/stateful_middleware.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 81f52c36..08153aed 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -34,10 +34,11 @@ class StatefulMiddleware extends StateManagementMiddleware { addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); return Future.value(node); } - var parentDirectory = getName(node.name).snakeCase; fileStrategy.commandCreated(WriteSymbolCommand( - node.UUID, parentDirectory, generationManager.generate(node))); + node.currentContext.tree.UUID, + node.name.snakeCase, + generationManager.generate(node))); node?.auxiliaryData?.stateGraph?.states?.forEach((state) { state.variation.node.currentContext.tree.data = node.managerData; From e3f46e900ceb63cfdecf64a58e359c6dc59fb73a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Fri, 4 Jun 2021 17:19:47 -0600 Subject: [PATCH 184/404] Normalizing absolute path to sketch --- lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index fffc4a7b..251f36a8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -148,7 +148,7 @@ ${parser.usage} if (!file || !exists) { handleError('$path is not a file'); } - MainInfo().sketchPath = path; + MainInfo().sketchPath = p.normalize(p.absolute(path)); InputDesignService(path); if (!Platform.environment.containsKey('SAC_ENDPOINT')) { From 4af08d800cf81873b41953d61e98097d0363599f Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Fri, 4 Jun 2021 18:10:51 -0600 Subject: [PATCH 185/404] Removed incorrect import from instance generation Fix references to ImportHelper.getName() --- .../flutter_project_builder/import_helper.dart | 9 +++++++++ .../middleware/state_management/bloc_middleware.dart | 3 ++- .../middleware/state_management/provider_middleware.dart | 4 ++-- .../middleware/state_management/riverpod_middleware.dart | 6 ++++-- .../middleware/state_management/stateful_middleware.dart | 3 ++- .../generators/symbols/pb_instancesym_gen.dart | 8 -------- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 67b85814..e93af0f6 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/generation/flutter_project_builder/file_writer_observer.dart'; import 'package:path/path.dart' as p; +import 'package:recase/recase.dart'; class ImportHelper implements FileWriterObserver { final Map> imports = {}; @@ -101,4 +102,12 @@ class ImportHelper implements FileWriterObserver { @override void fileCreated(String filePath, String fileUUID) => addImport(filePath, fileUUID); + + static String getName(String name) { + var index = name.indexOf('/'); + // Remove everything after the /. So if the name is SignUpButton/Default, we end up with SignUpButton as the name we produce. + return index < 0 + ? name + : name.replaceRange(index, name.length, '').pascalCase; + } } diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index c9b55367..cc9342ab 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; @@ -64,7 +65,7 @@ class BLoCMiddleware extends StateManagementMiddleware { fileStrategy.GENERATED_PROJECT_PATH, FileStructureStrategy.RELATIVE_VIEW_PATH, '${generalStateName.snakeCase}_bloc', - '${getName(symbolMaster.name).snakeCase}_bloc', + '${ImportHelper.getName(symbolMaster.name).snakeCase}_bloc', ); } diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 6d43bccf..1f651470 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -34,10 +34,10 @@ class ProviderMiddleware extends StateManagementMiddleware { var import = generateModelPath ? p.join(fileStrategy.RELATIVE_MODEL_PATH, - getName(symbolMaster.name).snakeCase) + ImportHelper.getName(symbolMaster.name).snakeCase) : p.join( FileStructureStrategy.RELATIVE_VIEW_PATH, - getName(symbolMaster.name).snakeCase, + ImportHelper.getName(symbolMaster.name).snakeCase, node.functionCallName.snakeCase); return p.join(fileStrategy.GENERATED_PROJECT_PATH, import); } diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 632e0b34..6ade4296 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -38,7 +38,7 @@ class RiverpodMiddleware extends StateManagementMiddleware { PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); return fileStrategy.GENERATED_PROJECT_PATH + fileStrategy.RELATIVE_MODEL_PATH + - '${getName(symbolMaster.name).snakeCase}.dart'; + '${ImportHelper.getName(symbolMaster.name).snakeCase}.dart'; } @override @@ -80,7 +80,9 @@ class RiverpodMiddleware extends StateManagementMiddleware { node, ); fileStrategy.commandCreated(WriteSymbolCommand( - node.currentContext.tree.UUID, getName(node.name).snakeCase, code, + node.currentContext.tree.UUID, + ImportHelper.getName(node.name).snakeCase, + code, symbolPath: fileStrategy.RELATIVE_MODEL_PATH)); return Future.value(null); } diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 08153aed..8a5b51ab 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; @@ -21,7 +22,7 @@ class StatefulMiddleware extends StateManagementMiddleware { var path = p.join( fileStrategy.GENERATED_PROJECT_PATH, FileStructureStrategy.RELATIVE_VIEW_PATH, - getName(symbolMaster.name).snakeCase, + ImportHelper.getName(symbolMaster.name).snakeCase, node.functionCallName.snakeCase); return path; } diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 8f843e42..66440c4a 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -97,14 +97,6 @@ class PBSymbolInstanceGenerator extends PBGenerator { symName = PBInputFormatter.formatLabel(symName, destroyDigits: false, spaceToUnderscore: false, isTitle: true); - var path = 'symbols'; - if (masterSymbol.name.contains('/')) { - path = ImportHelper.getName(masterSymbol.name).snakeCase; - } - - managerData.addImport(FlutterImport( - 'view/$path/${symName.snakeCase}.dart', MainInfo().projectName)); - // if this symbol is overridable, then put variable name + null check var overrideProp = SN_UUIDtoVarName[UUID + '_symbolID']; if (overrideProp != null) { From 26538fd9d7ca2a91fcd45649c0ddcaab3621574e Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 6 Jun 2021 13:35:07 -0600 Subject: [PATCH 186/404] Tweaked provider test --- .../state_management/provider_middleware.dart | 2 +- test/lib/middleware/provider_test.dart | 21 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 1f651470..00ece75e 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -129,6 +129,6 @@ class ProviderMiddleware extends StateManagementMiddleware { )); }); - return Future.value(null); + return Future.value(node); } } diff --git a/test/lib/middleware/provider_test.dart b/test/lib/middleware/provider_test.dart index b3cad85f..3f718508 100644 --- a/test/lib/middleware/provider_test.dart +++ b/test/lib/middleware/provider_test.dart @@ -44,13 +44,15 @@ class MockIntermediateVariation extends Mock implements IntermediateVariation {} class MockTree extends Mock implements PBIntermediateTree {} +class MockConfig extends Mock implements ProviderGenerationConfiguration {} + void main() { group('Middlewares Tests', () { - var config = ProviderGenerationConfiguration(); + var mockConfig = MockConfig(); var testingPath = '${Directory.current.path}/test/lib/middleware/'; var mockPBGenerationManager = MockPBGenerationManager(); var providerMiddleware = - ProviderMiddleware(mockPBGenerationManager, config); + ProviderMiddleware(mockPBGenerationManager, mockConfig); var node = MockPBIntermediateNode(); var node2 = MockPBIntermediateNode(); var mockContext = MockContext(); @@ -68,6 +70,7 @@ void main() { var mockIntermediateState = MockIntermediateState(); var mockIntermediateVariation = MockIntermediateVariation(); var mockTree = MockTree(); + var tree = PBIntermediateTree('test'); setUp(() async { /// Nodes set up @@ -103,11 +106,19 @@ void main() { when(mockContext.project).thenReturn(mockProject); when(mockContext.tree).thenReturn(mockTree); + // Tree + when(mockTree.rootNode).thenReturn(node); + when(mockTree.iterator).thenReturn([node].iterator); + tree.rootNode = node; + /// Project when(mockProject.genProjectData).thenReturn(mockPBGenerationProjectData); when(mockProject.forest).thenReturn([]); - when(config.fileStructureStrategy) + + // Configuration + when(mockConfig.fileStructureStrategy) .thenReturn(providerFileStructureStrategy); + when(mockConfig.registeredModels).thenReturn({}); /// PBGenerationManager when(mockPBGenerationManager.generate(any)).thenReturn('code'); @@ -118,8 +129,8 @@ void main() { test('Provider Strategy Test', () async { await providerFileStructureStrategy.setUpDirectories(); - var tempNode = await providerMiddleware.applyMiddleware(mockTree); - expect(tempNode is PBIntermediateNode, true); + var tempNode = await providerMiddleware.applyMiddleware(tree); + expect(tempNode is PBIntermediateTree, true); expect(await File('${testingPath}lib/models/some_element.dart').exists(), true); }); From d1ed8a0f6984106750775902cbac22064f57e4be Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 6 Jun 2021 13:37:34 -0600 Subject: [PATCH 187/404] Clean up provider test --- test/lib/middleware/provider_test.dart | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/lib/middleware/provider_test.dart b/test/lib/middleware/provider_test.dart index 3f718508..62349c06 100644 --- a/test/lib/middleware/provider_test.dart +++ b/test/lib/middleware/provider_test.dart @@ -42,8 +42,6 @@ class MockIntermediateState extends Mock implements IntermediateState {} class MockIntermediateVariation extends Mock implements IntermediateVariation {} -class MockTree extends Mock implements PBIntermediateTree {} - class MockConfig extends Mock implements ProviderGenerationConfiguration {} void main() { @@ -69,7 +67,6 @@ void main() { var mockDirectedStateGraph = MockDirectedStateGraph(); var mockIntermediateState = MockIntermediateState(); var mockIntermediateVariation = MockIntermediateVariation(); - var mockTree = MockTree(); var tree = PBIntermediateTree('test'); setUp(() async { @@ -104,11 +101,9 @@ void main() { /// Context when(mockContext.project).thenReturn(mockProject); - when(mockContext.tree).thenReturn(mockTree); + when(mockContext.tree).thenReturn(tree); // Tree - when(mockTree.rootNode).thenReturn(node); - when(mockTree.iterator).thenReturn([node].iterator); tree.rootNode = node; /// Project From d6f19a110458ee0345bf430e053c014e4e17282d Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 6 Jun 2021 13:58:12 -0600 Subject: [PATCH 188/404] Fixed stateful unit test --- .../state_management/stateful_middleware.dart | 2 +- test/lib/middleware/stateful_test.dart | 34 ++++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 8a5b51ab..fb3aed72 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -48,6 +48,6 @@ class StatefulMiddleware extends StateManagementMiddleware { state.variation.node.name.snakeCase, generationManager.generate(state.variation.node))); }); - return Future.value(null); + return Future.value(node); } } diff --git a/test/lib/middleware/stateful_test.dart b/test/lib/middleware/stateful_test.dart index 3910a676..fe3e3508 100644 --- a/test/lib/middleware/stateful_test.dart +++ b/test/lib/middleware/stateful_test.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:path/path.dart' as p; import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/stateful_middleware.dart'; @@ -8,7 +9,7 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_project_d import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -32,14 +33,15 @@ class MockPBGenerationViewData extends Mock implements PBGenerationViewData {} class MockPBGenerator extends Mock implements PBGenerator {} -class MockTree extends Mock implements PBIntermediateTree {} +class MockConfig extends Mock implements ProviderGenerationConfiguration {} void main() { group('Middlewares Tests', () { - var config = StatefulGenerationConfiguration(); + var mockConfig = MockConfig(); var testingPath = '${Directory.current.path}/test/lib/middleware/'; var mockPBGenerationManager = MockPBGenerationManager(); - var bLoCMiddleware = StatefulMiddleware(mockPBGenerationManager, config); + var bLoCMiddleware = + StatefulMiddleware(mockPBGenerationManager, mockConfig); var node = MockPBIntermediateNode(); var node2 = MockPBIntermediateNode(); var mockContext = MockContext(); @@ -56,7 +58,7 @@ void main() { var mockDirectedStateGraph = MockDirectedStateGraph(); var mockIntermediateState = MockIntermediateState(); var mockIntermediateVariation = MockIntermediateVariation(); - var mockTree = MockTree(); + var tree = PBIntermediateTree('test'); setUp(() async { /// Set up nodes @@ -86,12 +88,18 @@ void main() { /// Context when(mockContext.project).thenReturn(mockProject); - when(mockContext.tree).thenReturn(mockTree); + when(mockContext.tree).thenReturn(tree); + + // Tree + tree.rootNode = node; /// Project when(mockProject.genProjectData).thenReturn(mockPBGenerationProjectData); when(mockProject.forest).thenReturn([]); - when(config.fileStructureStrategy).thenReturn(mockFileStructureStrategy); + + // Configuration + when(mockConfig.fileStructureStrategy) + .thenReturn(mockFileStructureStrategy); /// PBGenerationManager when(mockPBGenerationManager.generate(node)).thenReturn('codeForBlue\n'); @@ -106,16 +114,16 @@ void main() { test('Stateful Strategy Test', () async { var relativeViewPath = FileStructureStrategy.RELATIVE_VIEW_PATH; await mockFileStructureStrategy.setUpDirectories(); - var tempNode = await bLoCMiddleware.applyMiddleware(mockTree); - expect(tempNode is PBIntermediateNode, true); + var tempNode = await bLoCMiddleware.applyMiddleware(tree); + expect(tempNode is PBIntermediateTree, true); expect( - await File( - '${testingPath}${relativeViewPath}some_element/some_element_blue.dart') + await File(p.join( + testingPath, relativeViewPath, 'some_element_blue.dart')) .exists(), true); expect( - await File( - '${testingPath}${relativeViewPath}some_element/some_element_green.dart') + await File(p.join( + testingPath, relativeViewPath, 'some_element_green.dart')) .exists(), true); }); From ae83204d4bfffe1949fbc6249d4355f27d1a5ef6 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 6 Jun 2021 14:36:28 -0600 Subject: [PATCH 189/404] Fix bloc middleware filestrategy and unit test. --- .../state_management/bloc_middleware.dart | 6 +++--- test/lib/middleware/bloc_test.dart | 21 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index cc9342ab..bb136f5f 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -75,8 +75,8 @@ class BLoCMiddleware extends StateManagementMiddleware { node.currentContext.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); - var fileStrategy = node.currentContext.project.fileStructureStrategy - as FlutterFileStructureStrategy; + var fileStrategy = + configuration.fileStructureStrategy as FlutterFileStructureStrategy; /// Incase of SymbolInstance if (node is PBSharedInstanceIntermediateNode) { @@ -153,6 +153,6 @@ class BLoCMiddleware extends StateManagementMiddleware { ), relativePath: parentDirectory)); - return Future.value(null); + return Future.value(node); } } diff --git a/test/lib/middleware/bloc_test.dart b/test/lib/middleware/bloc_test.dart index cc3fa7b5..8457d1f4 100644 --- a/test/lib/middleware/bloc_test.dart +++ b/test/lib/middleware/bloc_test.dart @@ -25,8 +25,6 @@ class MockContext extends Mock implements PBContext {} class MockProject extends Mock implements PBProject {} -class MockTree extends Mock implements PBIntermediateTree {} - class MockPBGenerationProjectData extends Mock implements PBGenerationProjectData {} @@ -34,12 +32,14 @@ class MockPBGenerationViewData extends Mock implements PBGenerationViewData {} class MockPBGenerator extends Mock implements PBGenerator {} +class MockConfig extends Mock implements BLoCGenerationConfiguration {} + void main() { group('Middlewares Tests', () { - var genConfig = BLoCGenerationConfiguration(); + var mockConfig = MockConfig(); var testingPath = '${Directory.current.path}/test/lib/middleware/'; var mockPBGenerationManager = MockPBGenerationManager(); - var bLoCMiddleware = BLoCMiddleware(mockPBGenerationManager, genConfig); + var bLoCMiddleware = BLoCMiddleware(mockPBGenerationManager, mockConfig); var node = MockPBIntermediateNode(); var node2 = MockPBIntermediateNode(); var mockContext = MockContext(); @@ -56,7 +56,7 @@ void main() { var mockDirectedStateGraph = MockDirectedStateGraph(); var mockIntermediateState = MockIntermediateState(); var mockIntermediateVariation = MockIntermediateVariation(); - var mockTree = MockTree(); + var tree = PBIntermediateTree('tree'); setUp(() async { /// Set up nodes @@ -86,12 +86,15 @@ void main() { /// Context when(mockContext.project).thenReturn(mockProject); - when(mockContext.tree).thenReturn(mockTree); + when(mockContext.tree).thenReturn(tree); + + // Tree + tree.rootNode = node; /// Project when(mockProject.genProjectData).thenReturn(mockPBGenerationProjectData); when(mockProject.forest).thenReturn([]); - when(genConfig.fileStructureStrategy) + when(mockConfig.fileStructureStrategy) .thenReturn(mockFileStructureStrategy); /// PBGenerationManager @@ -107,8 +110,8 @@ void main() { test('BLoC Strategy Test', () async { var relativeViewPath = FileStructureStrategy.RELATIVE_VIEW_PATH; await mockFileStructureStrategy.setUpDirectories(); - var tempNode = await bLoCMiddleware.applyMiddleware(mockTree); - expect(tempNode is PBIntermediateNode, true); + var tempNode = await bLoCMiddleware.applyMiddleware(tree); + expect(tempNode is PBIntermediateTree, true); expect( await File( '${testingPath}${relativeViewPath}some_element_bloc/some_element_bloc.dart') From f5fa43d37a6dfd6d54be8908fd0955124b14b493 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 6 Jun 2021 15:05:40 -0600 Subject: [PATCH 190/404] Fix misc unit tests --- lib/controllers/interpret.dart | 5 ----- test/lib/controllers/interpret_test.dart | 1 - test/lib/generation/import_test.dart | 2 +- .../input_services/edge_adjacent_detection_test.dart | 2 ++ test/lib/output_services/project_builder_test.dart | 10 ++++++---- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 319b14f8..37f6bd40 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -4,9 +4,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service import 'package:parabeac_core/input/helper/design_project.dart'; import 'package:parabeac_core/input/helper/design_page.dart'; import 'package:parabeac_core/input/helper/design_screen.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -18,7 +16,6 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orient import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_visual_generation_service.dart'; -import 'package:meta/meta.dart'; import 'package:quick_log/quick_log.dart'; import 'main_info.dart'; @@ -34,8 +31,6 @@ class Interpret { return _interpret; } - @visibleForTesting - String projectName; PBProject _pb_project; PBSymbolLinkerService _pbSymbolLinkerService; PBPrototypeLinkerService _pbPrototypeLinkerService; diff --git a/test/lib/controllers/interpret_test.dart b/test/lib/controllers/interpret_test.dart index 3f257069..eeec726e 100644 --- a/test/lib/controllers/interpret_test.dart +++ b/test/lib/controllers/interpret_test.dart @@ -13,7 +13,6 @@ void main() { interpret = Interpret(); interpret.init(nameOfProject, PBConfiguration.genericConfiguration()); expect(interpret, isNotNull); - expect(interpret.projectName, nameOfProject); }); test('Should return a PBIntermediateTree from a SketchNodeTree', () { diff --git a/test/lib/generation/import_test.dart b/test/lib/generation/import_test.dart index d7e67c89..79a30152 100644 --- a/test/lib/generation/import_test.dart +++ b/test/lib/generation/import_test.dart @@ -114,7 +114,7 @@ void main() { var command = WriteScreenCommand( 'UUID', 'some_dart_page.dart', 'homescreen/', 'dummy code'); await command.write(_fileStructureStrategy); - expect(importHelper.getImport('UUID'), completePath); + expect(importHelper.getImport('UUID').first, completePath); }); }); } diff --git a/test/lib/input_services/edge_adjacent_detection_test.dart b/test/lib/input_services/edge_adjacent_detection_test.dart index 22cbe587..70b7c29e 100644 --- a/test/lib/input_services/edge_adjacent_detection_test.dart +++ b/test/lib/input_services/edge_adjacent_detection_test.dart @@ -1,4 +1,5 @@ import 'package:mockito/mockito.dart'; +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; @@ -26,6 +27,7 @@ void main() { setUp(() { sketchNode = ShapePathMock(); context = ContextMock(); + MainInfo().outputPath = ''; when(sketchNode.points).thenReturn([ { diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index 5f18ef1b..77fe904d 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -6,7 +6,7 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_project_d import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; @@ -30,6 +30,8 @@ class MockData extends Mock implements IntermediateAuxiliaryData {} class MockContext extends Mock implements PBContext {} +class MockConfig extends Mock implements GenerationConfiguration {} + void main() { group('Project Builder Test', () { var projectBuilder; @@ -56,7 +58,7 @@ void main() { MockContext context; setUp(() async { - var config = StatefulGenerationConfiguration(); + var mockConfig = MockConfig(); MainInfo().cwd = Directory.current; MainInfo().outputPath = '${Directory.current.path}/test/lib/output_services/'; @@ -101,9 +103,9 @@ void main() { fss = FlutterFileStructureStrategy(outputPath, PBFlutterWriter(), project); await fss.setUpDirectories(); - when(config.fileStructureStrategy).thenReturn(fss); + when(mockConfig.fileStructureStrategy).thenReturn(fss); - projectBuilder = FlutterProjectBuilder(config, + projectBuilder = FlutterProjectBuilder(mockConfig, project: project, pageWriter: PBFlutterWriter()); }); test( From ae382294dac359422249f3371adc422d8686ac92 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 6 Jun 2021 15:08:26 -0600 Subject: [PATCH 191/404] Returning null in handleStatefulNode where necessary This breaks stateful management unit tests but is necessary in order to not add duplicate commands. --- .../generators/middleware/state_management/bloc_middleware.dart | 2 +- .../middleware/state_management/provider_middleware.dart | 2 +- .../middleware/state_management/stateful_middleware.dart | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index bb136f5f..b80d8ebc 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -153,6 +153,6 @@ class BLoCMiddleware extends StateManagementMiddleware { ), relativePath: parentDirectory)); - return Future.value(node); + return Future.value(null); } } diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 00ece75e..1f651470 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -129,6 +129,6 @@ class ProviderMiddleware extends StateManagementMiddleware { )); }); - return Future.value(node); + return Future.value(null); } } diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index fb3aed72..8a5b51ab 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -48,6 +48,6 @@ class StatefulMiddleware extends StateManagementMiddleware { state.variation.node.name.snakeCase, generationManager.generate(state.variation.node))); }); - return Future.value(node); + return Future.value(null); } } From 23cb461458b27611c929a7b819316659b9046819 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 6 Jun 2021 16:28:52 -0600 Subject: [PATCH 192/404] Fix stateful unit tests --- test/lib/middleware/bloc_test.dart | 38 +++++++------------------- test/lib/middleware/provider_test.dart | 32 ++++++++++++---------- test/lib/middleware/stateful_test.dart | 35 ++++++------------------ 3 files changed, 37 insertions(+), 68 deletions(-) diff --git a/test/lib/middleware/bloc_test.dart b/test/lib/middleware/bloc_test.dart index 8457d1f4..c8a7688e 100644 --- a/test/lib/middleware/bloc_test.dart +++ b/test/lib/middleware/bloc_test.dart @@ -7,9 +7,7 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -34,10 +32,11 @@ class MockPBGenerator extends Mock implements PBGenerator {} class MockConfig extends Mock implements BLoCGenerationConfiguration {} +class MockFileStrategy extends Mock implements FlutterFileStructureStrategy {} + void main() { group('Middlewares Tests', () { var mockConfig = MockConfig(); - var testingPath = '${Directory.current.path}/test/lib/middleware/'; var mockPBGenerationManager = MockPBGenerationManager(); var bLoCMiddleware = BLoCMiddleware(mockPBGenerationManager, mockConfig); var node = MockPBIntermediateNode(); @@ -47,11 +46,7 @@ void main() { var mockPBGenerationProjectData = MockPBGenerationProjectData(); var mockPBGenerationViewData = MockPBGenerationViewData(); var mockPBGenerator = MockPBGenerator(); - var mockFileStructureStrategy = FlutterFileStructureStrategy( - testingPath, - PBFlutterWriter(), - mockProject, - ); + var mockFileStructureStrategy = MockFileStrategy(); var mockIntermediateAuxiliaryData = MockIntermediateAuxiliaryData(); var mockDirectedStateGraph = MockDirectedStateGraph(); var mockIntermediateState = MockIntermediateState(); @@ -108,29 +103,16 @@ void main() { }); test('BLoC Strategy Test', () async { - var relativeViewPath = FileStructureStrategy.RELATIVE_VIEW_PATH; await mockFileStructureStrategy.setUpDirectories(); var tempNode = await bLoCMiddleware.applyMiddleware(tree); - expect(tempNode is PBIntermediateTree, true); - expect( - await File( - '${testingPath}${relativeViewPath}some_element_bloc/some_element_bloc.dart') - .exists(), - true); - expect( - await File( - '${testingPath}${relativeViewPath}some_element_bloc/some_element_event.dart') - .exists(), - true); - expect( - await File( - '${testingPath}${relativeViewPath}some_element_bloc/some_element_state.dart') - .exists(), - true); - }); + expect(tempNode, isNull); + + var verification = + verify(mockFileStructureStrategy.commandCreated(captureAny)); - tearDownAll(() { - Process.runSync('rm', ['-rf', '${testingPath}lib']); + expect(verification.captured[0].fileName, contains('state')); + expect(verification.captured[1].fileName, contains('event')); + expect(verification.captured[2].fileName, contains('bloc')); }); }); } diff --git a/test/lib/middleware/provider_test.dart b/test/lib/middleware/provider_test.dart index 62349c06..629fa867 100644 --- a/test/lib/middleware/provider_test.dart +++ b/test/lib/middleware/provider_test.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/provider_middleware.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; @@ -7,7 +6,6 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_project_d import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -44,10 +42,13 @@ class MockIntermediateVariation extends Mock implements IntermediateVariation {} class MockConfig extends Mock implements ProviderGenerationConfiguration {} +class MockFileStrategy extends Mock implements ProviderFileStructureStrategy {} + void main() { + final modelPath = 'lib/models/'; + final viewPath = 'lib/widgets'; group('Middlewares Tests', () { var mockConfig = MockConfig(); - var testingPath = '${Directory.current.path}/test/lib/middleware/'; var mockPBGenerationManager = MockPBGenerationManager(); var providerMiddleware = ProviderMiddleware(mockPBGenerationManager, mockConfig); @@ -58,11 +59,8 @@ void main() { var mockPBGenerationProjectData = MockPBGenerationProjectData(); var mockPBGenerationViewData = MockPBGenerationViewData(); var mockPBGenerator = MockPBGenerator(); - var providerFileStructureStrategy = ProviderFileStructureStrategy( - testingPath, - PBFlutterWriter(), - mockProject, - ); + var providerFileStructureStrategy = MockFileStrategy(); + var mockIntermediateAuxiliaryData = MockIntermediateAuxiliaryData(); var mockDirectedStateGraph = MockDirectedStateGraph(); var mockIntermediateState = MockIntermediateState(); @@ -120,18 +118,24 @@ void main() { /// PBGenerationProjectData when(mockPBGenerationProjectData.addDependencies('', '')).thenReturn(''); + + // FileStructureStrategy + when(providerFileStructureStrategy.RELATIVE_MODEL_PATH) + .thenReturn(modelPath); }); test('Provider Strategy Test', () async { await providerFileStructureStrategy.setUpDirectories(); var tempNode = await providerMiddleware.applyMiddleware(tree); - expect(tempNode is PBIntermediateTree, true); - expect(await File('${testingPath}lib/models/some_element.dart').exists(), - true); - }); + expect(tempNode, isNull); + var verification = + verify(providerFileStructureStrategy.commandCreated(captureAny)); + + expect(verification.callCount, 3); - tearDownAll(() { - Process.runSync('rm', ['-rf', '${testingPath}lib']); + expect(verification.captured[0].symbolPath, contains(modelPath)); + expect(verification.captured[1].symbolPath, contains(viewPath)); + expect(verification.captured[2].symbolPath, contains(viewPath)); }); }); } diff --git a/test/lib/middleware/stateful_test.dart b/test/lib/middleware/stateful_test.dart index fe3e3508..6997cdcb 100644 --- a/test/lib/middleware/stateful_test.dart +++ b/test/lib/middleware/stateful_test.dart @@ -1,6 +1,3 @@ -import 'dart:io'; -import 'package:path/path.dart' as p; - import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/stateful_middleware.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; @@ -8,9 +5,7 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -35,10 +30,11 @@ class MockPBGenerator extends Mock implements PBGenerator {} class MockConfig extends Mock implements ProviderGenerationConfiguration {} +class MockFileStrategy extends Mock implements FlutterFileStructureStrategy {} + void main() { group('Middlewares Tests', () { var mockConfig = MockConfig(); - var testingPath = '${Directory.current.path}/test/lib/middleware/'; var mockPBGenerationManager = MockPBGenerationManager(); var bLoCMiddleware = StatefulMiddleware(mockPBGenerationManager, mockConfig); @@ -49,11 +45,7 @@ void main() { var mockPBGenerationProjectData = MockPBGenerationProjectData(); var mockPBGenerationViewData = MockPBGenerationViewData(); var mockPBGenerator = MockPBGenerator(); - var mockFileStructureStrategy = FlutterFileStructureStrategy( - testingPath, - PBFlutterWriter(), - mockProject, - ); + var mockFileStructureStrategy = MockFileStrategy(); var mockIntermediateAuxiliaryData = MockIntermediateAuxiliaryData(); var mockDirectedStateGraph = MockDirectedStateGraph(); var mockIntermediateState = MockIntermediateState(); @@ -112,24 +104,15 @@ void main() { }); test('Stateful Strategy Test', () async { - var relativeViewPath = FileStructureStrategy.RELATIVE_VIEW_PATH; await mockFileStructureStrategy.setUpDirectories(); var tempNode = await bLoCMiddleware.applyMiddleware(tree); - expect(tempNode is PBIntermediateTree, true); - expect( - await File(p.join( - testingPath, relativeViewPath, 'some_element_blue.dart')) - .exists(), - true); - expect( - await File(p.join( - testingPath, relativeViewPath, 'some_element_green.dart')) - .exists(), - true); - }); + expect(tempNode, isNull); + + var verification = + verify(mockFileStructureStrategy.commandCreated(captureAny)); - tearDownAll(() { - Process.runSync('rm', ['-rf', '${testingPath}lib']); + expect(verification.captured[0].fileName, contains('blue')); + expect(verification.captured[1].fileName, contains('green')); }); }); } From f169aeb83c4bd6a8348f493bb3fd52add6bf9c66 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 6 Jun 2021 22:11:24 -0600 Subject: [PATCH 193/404] Fixed the style class in auxillary data class that coused runtime issues. --- .../state_management/intermediate_auxillary_data.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart index 3673a5c7..606ab3da 100644 --- a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart +++ b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/design_logic/pb_style.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/directed_state_graph.dart'; @@ -14,7 +15,7 @@ class IntermediateAuxiliaryData { String color; /// the style of the element (which can be overridden) - Style style; + PBStyle style; IntermediateAuxiliaryData({ this.stateGraph, From 4fb85264f106b3ac641d1823162456cced468f31 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Mon, 7 Jun 2021 13:40:03 -0600 Subject: [PATCH 194/404] BUGFIX the method generateEmptyVariable was not returning anything, making the widget inside the LayoutBuilder statement null --- .../middleware/state_management/utils/middleware_utils.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 04e503c3..450ccb98 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -102,7 +102,7 @@ class MiddlewareUtils { static String generateVariableBody(PBIntermediateNode node) { node.currentContext.sizingContext = SizingValueContext.PointValue; - (node?.generator?.generate(node ?? '', node.currentContext) ?? '') + ';'; + return (node?.generator?.generate(node ?? '', node.currentContext) ?? ''); } static String wrapOnLayout(String className) { From 705c32b16a5b53da1446f0c1dac0c1a6a2cd65a0 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Mon, 7 Jun 2021 17:14:00 -0600 Subject: [PATCH 195/404] WIP bugfix(463) now the generated code is being generated under the correct folder when a different name is specified. --- lib/controllers/controller.dart | 1 + .../flutter_project_builder.dart | 109 +++++++++++------- .../output_services/project_builder_test.dart | 4 +- 3 files changed, 74 insertions(+), 40 deletions(-) diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index a129048f..b6b63035 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -37,6 +37,7 @@ abstract class Controller { var fpb = FlutterProjectBuilder( MainInfo().configuration.generationConfiguration, project: pbProject, + genProjectAbsPath: configuration.genProjectPath, pageWriter: PBFlutterWriter()); await fpb.convertToFlutterProject(); diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index a488cfdb..95e62126 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -4,42 +4,74 @@ import 'package:path/path.dart' as p; import 'package:archive/archive.dart'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; -import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; -import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; -import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart'; -import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_linker.dart'; import 'package:quick_log/quick_log.dart'; -String pathToFlutterProject = '${MainInfo().outputPath}/temp/'; - +// String pathToFlutterProject = '${MainInfo().outputPath}/temp/'; + +/// The [FlutterProjectBuilder] generates the actual flutter project, +/// where the generated dart code will reside for the [project]. +/// +/// The [FlutterProjectBuilder] will construct the necessary files within the +/// [flutterDir] with the name of [projectName]. +/// Finally, it's going to generate all the required code by utilizing the [generationConfiguration]. +/// Make sure the [FlutterProjectBuilder] is getting the directory path that will contain the flutter project. +/// For example, if the Flutter project were to be `my/awesome/path/FlutterProject,` +/// the [flutterDir] would be `my/awesome/path,` while the project name is `FlutterProject.` class FlutterProjectBuilder { PBProject project; - var log = Logger('Project Builder'); + Logger log; PBPageWriter pageWriter; + /// The path of the directory where the [project] is going to be generated at. + final String flutterDir; + + /// The name that will be used for the generation of the [project] + /// + /// If no [projectName] is provided, the [PBProject.projectName] will + /// be used as the default value. + String projectName; + + /// The absolute path for the generated [project] + String genProjectAbsPath; + ///The [GenerationConfiguration] that is going to be use in the generation of the code /// ///This is going to be defaulted to [GenerationConfiguration] if nothing else is specified. GenerationConfiguration generationConfiguration; - FlutterProjectBuilder(this.generationConfiguration, - {this.project, this.pageWriter}) { + FlutterProjectBuilder( + this.generationConfiguration, { + this.project, + this.pageWriter, + this.projectName, + this.genProjectAbsPath, + this.flutterDir, + }) { + log = Logger(runtimeType.toString()); + + projectName ??= project.projectName; + genProjectAbsPath ??= p.join(flutterDir, projectName); + + if (genProjectAbsPath == null) { + log.error( + '[genProjectAbsPath] is null, caused by not providing both [projectName] & [flutterDir] or providing [genProjectAbsPath]'); + throw NullThrownError(); + } + generationConfiguration.pageWriter = pageWriter; } Future convertToFlutterProject({List rawImages}) async { try { - var createResult = Process.runSync( - 'flutter', ['create', '${project.projectName}'], + var createResult = Process.runSync('flutter', ['create', projectName], workingDirectory: MainInfo().outputPath); if (createResult.stderr != null && createResult.stderr.isNotEmpty) { log.error(createResult.stderr); @@ -54,13 +86,9 @@ class FlutterProjectBuilder { log.error(error.toString()); } - await Directory(p.join(pathToFlutterProject, 'assets/images')) + await Directory(p.join(genProjectAbsPath, 'assets/images')) .create(recursive: true) - .then((value) => { - // print(value), - }) .catchError((e) { - // print(e); log.error(e.toString()); }); @@ -70,22 +98,24 @@ class FlutterProjectBuilder { await FigmaAssetProcessor().processImageQueue(); } - var pngsPath = p.join(MainInfo().outputPath, 'pngs', '*'); Process.runSync( - '${MainInfo().cwd.path}/lib/generation/helperScripts/shell-proxy.sh', + p.join(MainInfo().cwd.path, + '/lib/generation/helperScripts/shell-proxy.sh'), [ - 'mv $pngsPath ${pathToFlutterProject}assets/images/' + 'mv ${p.join('./pngs', '*')} ${p.join(genProjectAbsPath, 'assets/images/')}' ], runInShell: true, environment: Platform.environment, - workingDirectory: '${pathToFlutterProject}assets/'); + workingDirectory: MainInfo().outputPath); // Add all images if (rawImages != null) { for (var image in rawImages) { if (image.name != null) { - var f = File( - '${pathToFlutterProject}assets/images/${image.name.replaceAll(" ", "")}.png'); + var f = File(p.setExtension( + p.join(genProjectAbsPath, 'assets/images/', + image.name.replaceAll(' ', '')), + '.png')); f.writeAsBytesSync(image.content); } } @@ -96,13 +126,14 @@ class FlutterProjectBuilder { project.sharedStyles.isNotEmpty && MainInfo().exportStyles) { try { - Directory('${pathToFlutterProject}lib/document/') + Directory(p.join(genProjectAbsPath, 'lib/document/')) .createSync(recursive: true); - WriteStyleClasses(); + WriteStyleClasses(genProjectAbsPath); - var s = File('${pathToFlutterProject}lib/document/shared_props.g.dart') - .openWrite(mode: FileMode.write, encoding: utf8); + var s = + File(p.join(genProjectAbsPath, 'lib/document/shared_props.g.dart')) + .openWrite(mode: FileMode.write, encoding: utf8); s.write('''${FlutterImport('dart:ui', null)} ${FlutterImport('flutter/material.dart', null)} @@ -123,28 +154,30 @@ class FlutterProjectBuilder { .generatePlatformAndOrientationInstance(project); Process.runSync( - '${MainInfo().cwd.path}/lib/generation/helperScripts/shell-proxy.sh', + p.join(MainInfo().cwd.path, + '/lib/generation/helperScripts/shell-proxy.sh'), ['rm -rf .dart_tool/build'], runInShell: true, environment: Platform.environment, - workingDirectory: '${MainInfo().outputPath}'); + workingDirectory: MainInfo().outputPath); // Remove pngs folder Process.runSync( - '${MainInfo().cwd.path}/lib/generation/helperScripts/shell-proxy.sh', - ['rm -rf ${MainInfo().outputPath}/pngs'], + p.join(MainInfo().cwd.path, + '/lib/generation/helperScripts/shell-proxy.sh'), + ['rm -rf ${p.join(MainInfo().outputPath, '/pngs')}'], runInShell: true, environment: Platform.environment, - workingDirectory: '${MainInfo().outputPath}'); + workingDirectory: MainInfo().outputPath); log.info( Process.runSync( 'dart', [ 'format', - '${pathToFlutterProject}bin', - '${pathToFlutterProject}lib', - '${pathToFlutterProject}test' + '${p.join(genProjectAbsPath, 'bin')}', + '${p.join(genProjectAbsPath, 'lib')}', + '${p.join(genProjectAbsPath, 'test')}' ], workingDirectory: MainInfo().outputPath) .stdout, @@ -152,9 +185,8 @@ class FlutterProjectBuilder { } } -void WriteStyleClasses() -{ - var s = File('${pathToFlutterProject}lib/document/Styles.g.dart') +void WriteStyleClasses(String pathToFlutterProject) { + var s = File(p.join(pathToFlutterProject, 'lib/document/Style.g.dart')) .openWrite(mode: FileMode.write, encoding: utf8); s.write(''' import 'dart:ui'; @@ -194,5 +226,4 @@ class SK_Style { '''); s.close(); - } diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index 77fe904d..b790a58a 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -106,7 +106,9 @@ void main() { when(mockConfig.fileStructureStrategy).thenReturn(fss); projectBuilder = FlutterProjectBuilder(mockConfig, - project: project, pageWriter: PBFlutterWriter()); + genProjectAbsPath: Directory.current.path, + project: project, + pageWriter: PBFlutterWriter()); }); test( '', From 73dfbfe599ebf7d4e8c8d777722e1aece5dc1a42 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 8 Jun 2021 16:16:37 -0600 Subject: [PATCH 196/404] Corrected provier output --- .../state_management/riverpod_middleware.dart | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 6ade4296..73a7cf18 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -2,6 +2,7 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.d import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart'; @@ -10,6 +11,7 @@ import 'package:parabeac_core/generation/generators/value_objects/template_strat import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; +import '../../pb_flutter_generator.dart'; import '../../pb_generation_manager.dart'; import '../../pb_variable.dart'; import 'package:recase/recase.dart'; @@ -67,23 +69,48 @@ class RiverpodMiddleware extends StateManagementMiddleware { addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); if (node.generator is! StringGeneratorAdapter) { - node.generator = StringGeneratorAdapter( - getConsumer(watcherName, node.functionCallName.camelCase)); + node.generator = StringGeneratorAdapter(getConsumer( + watcherName, 'currentWidget')); // node.functionCallName.camelCase } + return Future.value(node); } watcherName = getNameOfNode(node); - var code = MiddlewareUtils.generateChangeNotifierClass( - watcherName, - generationManager, - node, - ); - fileStrategy.commandCreated(WriteSymbolCommand( + var parentDirectory = ImportHelper.getName(node.name).snakeCase; + + // Generate model's imports + var modelGenerator = PBFlutterGenerator(ImportHelper(), + data: PBGenerationViewData() + ..addImport(FlutterImport('material.dart', 'flutter'))); + // Write model class for current node + var code = MiddlewareUtils.generateModelChangeNotifier( + watcherName, modelGenerator, node); + + [ + /// This generated the `changeNotifier` that goes under the [fileStrategy.RELATIVE_MODEL_PATH] + WriteSymbolCommand( node.currentContext.tree.UUID, - ImportHelper.getName(node.name).snakeCase, + parentDirectory, code, - symbolPath: fileStrategy.RELATIVE_MODEL_PATH)); + symbolPath: fileStrategy.RELATIVE_MODEL_PATH, + ), + // Generate default node's view page + WriteSymbolCommand(node.currentContext.tree.UUID, node.name.snakeCase, + generationManager.generate(node), + relativePath: parentDirectory), + ].forEach(fileStrategy.commandCreated); + + // Generate node's states' view pages + node.auxiliaryData?.stateGraph?.states?.forEach((state) { + fileStrategy.commandCreated(WriteSymbolCommand( + state.variation.node.currentContext.tree.UUID, + state.variation.node.name.snakeCase, + generationManager.generate(state.variation.node), + relativePath: parentDirectory, + )); + }); + return Future.value(null); } } From d7cda480899c65773b02f46b9ab8a7c8bb08ac7c Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 11 Jun 2021 16:35:07 -0600 Subject: [PATCH 197/404] Removed event page generator and changed bloc for cubit --- .../state_management/bloc_middleware.dart | 39 +++++-------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index b80d8ebc..0fdc2232 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -29,32 +29,21 @@ class BLoCMiddleware extends StateManagementMiddleware { return ''' ${generationManager.generateImports()} - part '${snakeName}_event.dart'; part '${snakeName}_state.dart'; - class ${pascalName}Bloc extends Bloc<${pascalName}Event, ${pascalName}State> { - ${pascalName}Bloc() : super(${initialStateName.pascalCase}State()); + class ${pascalName}Cubit extends Cubit<${pascalName}State> { + ${pascalName}Cubit() : super(${initialStateName.pascalCase}State()); - @override - Stream<${pascalName}State> mapEventToState( - ${pascalName}Event event, - ) async* { - // TODO: implement mapEventToState + void onGesture(){ + // TODO: Populate onGesture method + // + // You can check the current state of the Cubit by using the [state] variable from `super`. + // To change the current state, call the [emit()] method with the state of your choice. } } '''; } - String _createEventPage(String name) { - var pascalName = name.pascalCase; - return ''' - part of '${name.snakeCase}_bloc.dart'; - - @immutable - abstract class ${pascalName}Event {} - '''; - } - String getImportPath(PBSharedInstanceIntermediateNode node, FileStructureStrategy fileStrategy) { var generalStateName = node.functionCallName @@ -132,21 +121,11 @@ class BLoCMiddleware extends StateManagementMiddleware { stateBuffer.toString(), relativePath: parentDirectory)); - /// Creates event page - fileStrategy.commandCreated(WriteSymbolCommand( - - /// modified the [UUID] to prevent adding import because the event is - /// using `part of` syntax already when importing the bloc - 'EVENT${node.currentContext.tree.UUID}', - '${generalName}_event', - _createEventPage(parentState), - relativePath: parentDirectory)); - - /// Creates bloc page + /// Creates cubit page managerData.addImport(FlutterImport('meta.dart', 'meta')); fileStrategy.commandCreated(WriteSymbolCommand( node.currentContext.tree.UUID, - '${generalName}_bloc', + '${generalName}_cubit', _createBlocPage( parentState, node.name, From 614ad82ac4191170a3b54ece27d5174e3cc79281 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 11 Jun 2021 16:35:27 -0600 Subject: [PATCH 198/404] Remove UI components from states --- .../bloc_state_template_strategy.dart | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index ecf1d718..0e0cd83b 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -16,41 +16,25 @@ class BLoCStateTemplateStrategy extends TemplateStrategy { {args}) { var widgetName = retrieveNodeName(node); node.managerData.hasParams = true; - var returnStatement = node.generator.generate(node, generatorContext); node.managerData.hasParams = false; - var overrides = ''; - var overrideVars = ''; - if (node is PBSharedMasterNode && node.overridableProperties.isNotEmpty) { - node.overridableProperties.forEach((prop) { - overrides += '${prop.friendlyName}, '; - overrideVars += 'var ${prop.friendlyName};'; - }); - } return ''' ${isFirst ? _getHeader(manager) : ''} class ${node.name.pascalCase}State extends ${abstractClassName.pascalCase}State{ - ${manager.generateGlobalVariables()} - - $overrideVars - - ${widgetName + 'State'}(${(overrides.isNotEmpty ? '{$overrides}' : '')}){} - - @override - Widget get widget => $returnStatement; + ${widgetName + 'State'}(){} }'''; } String _getHeader(manager) { return ''' - part of '${abstractClassName.snakeCase}_bloc.dart'; + part of '${abstractClassName.snakeCase}_cubit.dart'; @immutable abstract class ${abstractClassName.pascalCase}State{ - Widget get widget; + } '''; } From b96ced44bdcfe076d59501d5c65783db175e0020 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 11 Jun 2021 17:26:34 -0600 Subject: [PATCH 199/404] Changed to LayoutBuilder for Bloc on screen --- .../state_management/bloc_middleware.dart | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 0fdc2232..5bd205b4 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -71,22 +71,29 @@ class BLoCMiddleware extends StateManagementMiddleware { if (node is PBSharedInstanceIntermediateNode) { var generalStateName = node.functionCallName .substring(0, node.functionCallName.lastIndexOf('/')); - - var globalVariableName = getVariableName(node.name.snakeCase); - managerData.addGlobalVariable(PBVariable(globalVariableName, 'var ', true, - '${generalStateName.pascalCase}Bloc()')); - - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); - - managerData.addToDispose('$globalVariableName.close()'); if (node.generator is! StringGeneratorAdapter) { + var nameWithCubit = '${generalStateName.pascalCase}Cubit'; + var nameWithState = '${generalStateName.pascalCase}State'; + var namewithToWidget = '${generalStateName.pascalCase}StateToWidget'; node.generator = StringGeneratorAdapter(''' - BlocBuilder<${generalStateName.pascalCase}Bloc, ${generalStateName.pascalCase}State>( - cubit: $globalVariableName, - builder: (context, state) => state.widget - ) + LayoutBuilder( + builder: (context, constraints){ + return BlocProvider<$nameWithCubit>( + create: (context) => $nameWithCubit(), + child: BlocBuilder<$nameWithCubit,$nameWithState>( + builder: (context, state){ + return GestureDetector( + child: $namewithToWidget(), + onTap: () => context.read<$nameWithCubit>().onGesture(), + ); + } + ) + ); + } + ) '''); } + return Future.value(node); } var parentState = getNameOfNode(node); From 1ff00f43f414f640bd06724a2955aa214e707657 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Sun, 13 Jun 2021 19:25:35 -0600 Subject: [PATCH 200/404] Added Function for state changing WIP --- .../state_management/bloc_middleware.dart | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 5bd205b4..973109c5 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -74,7 +74,9 @@ class BLoCMiddleware extends StateManagementMiddleware { if (node.generator is! StringGeneratorAdapter) { var nameWithCubit = '${generalStateName.pascalCase}Cubit'; var nameWithState = '${generalStateName.pascalCase}State'; - var namewithToWidget = '${generalStateName.pascalCase}StateToWidget'; + var master = + PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); + var namewithToWidget = '${master.name.pascalCase}StateToWidget'; node.generator = StringGeneratorAdapter(''' LayoutBuilder( builder: (context, constraints){ @@ -83,7 +85,7 @@ class BLoCMiddleware extends StateManagementMiddleware { child: BlocBuilder<$nameWithCubit,$nameWithState>( builder: (context, state){ return GestureDetector( - child: $namewithToWidget(), + child: $namewithToWidget(state, constraints), onTap: () => context.read<$nameWithCubit>().onGesture(), ); } @@ -102,6 +104,7 @@ class BLoCMiddleware extends StateManagementMiddleware { var states = [node]; var stateBuffer = StringBuffer(); + var mapBuffer = StringBuffer(); node?.auxiliaryData?.stateGraph?.states?.forEach((state) { states.add(state.variation.node); @@ -115,8 +118,10 @@ class BLoCMiddleware extends StateManagementMiddleware { abstractClassName: parentState, ); stateBuffer.write(generationManager.generate(element)); + isFirst = false; }); + mapBuffer.write(_makeStateToWidgetFunction(node)); /// Creates state page fileStrategy.commandCreated(WriteSymbolCommand( @@ -128,6 +133,16 @@ class BLoCMiddleware extends StateManagementMiddleware { stateBuffer.toString(), relativePath: parentDirectory)); + /// Creates map page + fileStrategy.commandCreated(WriteSymbolCommand( + + /// modified the [UUID] to prevent adding import because the event is + /// using `part of` syntax already when importing the bloc + 'MAP${node.currentContext.tree.UUID}', + '${generalName}_map', + mapBuffer.toString(), + relativePath: parentDirectory)); + /// Creates cubit page managerData.addImport(FlutterImport('meta.dart', 'meta')); fileStrategy.commandCreated(WriteSymbolCommand( @@ -141,4 +156,36 @@ class BLoCMiddleware extends StateManagementMiddleware { return Future.value(null); } + + String _makeStateToWidgetFunction(PBIntermediateNode element) { + var stateBuffer = StringBuffer(); + stateBuffer.write( + 'Widget ${element.name.camelCase}StateToWidget( ${element.name.pascalCase}State state, BoxConstraints constraints) {'); + for (var i = 0; i < element.auxiliaryData.stateGraph.states.length; i++) { + if (i == 0) { + stateBuffer.write(_getStateLogic( + element.auxiliaryData.stateGraph.states[i].variation.node, 'if')); + } else { + { + stateBuffer.write(_getStateLogic( + element.auxiliaryData.stateGraph.states[i].variation.node, + 'else if')); + } + } + } + + stateBuffer + .write('return ${element.name.pascalCase}State(constraints); \n }'); + + return stateBuffer.toString(); + } + + String _getStateLogic(PBIntermediateNode node, String statement) { + print('hi'); + return ''' + $statement (state is ${node.name.pascalCase}State){ + return ${node.name.pascalCase}State(constraints); + } \n + '''; + } } From bbc61ccb103635351757e3f862f3ebd188f82906 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Sun, 13 Jun 2021 22:01:39 -0600 Subject: [PATCH 201/404] Added missing arguments --- .../template_strategy/bloc_state_template_strategy.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index 0e0cd83b..064da0ec 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -23,7 +23,7 @@ ${isFirst ? _getHeader(manager) : ''} class ${node.name.pascalCase}State extends ${abstractClassName.pascalCase}State{ - ${widgetName + 'State'}(){} + ${widgetName + 'State'}(BoxConstraints constraints){} }'''; } From b1d273778b988f67eaf8e12f2e0658fecf0cded2 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Sun, 13 Jun 2021 22:01:59 -0600 Subject: [PATCH 202/404] Added some imports still WIP --- .../state_management/bloc_middleware.dart | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 973109c5..940bf71e 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -32,7 +32,8 @@ class BLoCMiddleware extends StateManagementMiddleware { part '${snakeName}_state.dart'; class ${pascalName}Cubit extends Cubit<${pascalName}State> { - ${pascalName}Cubit() : super(${initialStateName.pascalCase}State()); + var constraints; + ${pascalName}Cubit(this.constraints) : super(${initialStateName.pascalCase}State(constraints)); void onGesture(){ // TODO: Populate onGesture method @@ -64,6 +65,7 @@ class BLoCMiddleware extends StateManagementMiddleware { node.currentContext.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); + var fileStrategy = configuration.fileStructureStrategy as FlutterFileStructureStrategy; @@ -76,7 +78,8 @@ class BLoCMiddleware extends StateManagementMiddleware { var nameWithState = '${generalStateName.pascalCase}State'; var master = PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); - var namewithToWidget = '${master.name.pascalCase}StateToWidget'; + var namewithToWidget = '${master.name.camelCase}StateToWidget'; + node.generator = StringGeneratorAdapter(''' LayoutBuilder( builder: (context, constraints){ @@ -121,7 +124,6 @@ class BLoCMiddleware extends StateManagementMiddleware { isFirst = false; }); - mapBuffer.write(_makeStateToWidgetFunction(node)); /// Creates state page fileStrategy.commandCreated(WriteSymbolCommand( @@ -134,6 +136,7 @@ class BLoCMiddleware extends StateManagementMiddleware { relativePath: parentDirectory)); /// Creates map page + mapBuffer.write(_makeStateToWidgetFunction(node)); fileStrategy.commandCreated(WriteSymbolCommand( /// modified the [UUID] to prevent adding import because the event is @@ -159,6 +162,13 @@ class BLoCMiddleware extends StateManagementMiddleware { String _makeStateToWidgetFunction(PBIntermediateNode element) { var stateBuffer = StringBuffer(); + var elementName = + element.name.substring(0, element.name.lastIndexOf('/')).snakeCase; + stateBuffer.write("import 'package:flutter/material.dart';"); + // TODO: replace dynamically + stateBuffer.write( + "import 'package:temp/widgets/${elementName}_bloc/${elementName}_cubit.dart';"); + stateBuffer.write( 'Widget ${element.name.camelCase}StateToWidget( ${element.name.pascalCase}State state, BoxConstraints constraints) {'); for (var i = 0; i < element.auxiliaryData.stateGraph.states.length; i++) { From 269ee2b6fe34cb1c0408d912eb1d2158ece38e86 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 13 Jun 2021 22:38:24 -0600 Subject: [PATCH 203/404] Fix references to symbols in state to widget function. --- .../middleware/state_management/bloc_middleware.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 940bf71e..8a5a4433 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -185,16 +185,15 @@ class BLoCMiddleware extends StateManagementMiddleware { } stateBuffer - .write('return ${element.name.pascalCase}State(constraints); \n }'); + .write('return ${element.name.pascalCase}(constraints); \n }'); return stateBuffer.toString(); } String _getStateLogic(PBIntermediateNode node, String statement) { - print('hi'); return ''' $statement (state is ${node.name.pascalCase}State){ - return ${node.name.pascalCase}State(constraints); + return ${node.name.pascalCase}(constraints); } \n '''; } From 132645a7a8c15ac6de4f2e17a51b672e540b27cf Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sun, 13 Jun 2021 22:42:54 -0600 Subject: [PATCH 204/404] Removed constraints UI logic from bloc --- .../middleware/state_management/bloc_middleware.dart | 6 ++---- .../template_strategy/bloc_state_template_strategy.dart | 9 +-------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 8a5a4433..a6243d23 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -32,8 +32,7 @@ class BLoCMiddleware extends StateManagementMiddleware { part '${snakeName}_state.dart'; class ${pascalName}Cubit extends Cubit<${pascalName}State> { - var constraints; - ${pascalName}Cubit(this.constraints) : super(${initialStateName.pascalCase}State(constraints)); + ${pascalName}Cubit(this.constraints) : super(${initialStateName.pascalCase}State()); void onGesture(){ // TODO: Populate onGesture method @@ -184,8 +183,7 @@ class BLoCMiddleware extends StateManagementMiddleware { } } - stateBuffer - .write('return ${element.name.pascalCase}(constraints); \n }'); + stateBuffer.write('return ${element.name.pascalCase}(constraints); \n }'); return stateBuffer.toString(); } diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index 064da0ec..3b199e4e 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -1,7 +1,5 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:recase/recase.dart'; @@ -14,18 +12,13 @@ class BLoCStateTemplateStrategy extends TemplateStrategy { String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, PBContext generatorContext, {args}) { - var widgetName = retrieveNodeName(node); node.managerData.hasParams = true; node.managerData.hasParams = false; return ''' ${isFirst ? _getHeader(manager) : ''} -class ${node.name.pascalCase}State extends ${abstractClassName.pascalCase}State{ - - ${widgetName + 'State'}(BoxConstraints constraints){} - -}'''; +class ${node.name.pascalCase}State extends ${abstractClassName.pascalCase}State{}'''; } String _getHeader(manager) { From 64c9012571f321dd49caac1bd5ae193779f75f7c Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 14 Jun 2021 15:11:57 -0600 Subject: [PATCH 205/404] Generate view separately from bloc model logiv. --- .../state_management/bloc_middleware.dart | 24 +++++++++++++------ .../bloc_file_structure_strategy.dart | 2 ++ .../bloc_generation_configuration.dart | 6 ++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index a6243d23..9490e9c9 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -1,9 +1,8 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; -import 'package:parabeac_core/generation/generators/pb_variable.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -66,7 +65,7 @@ class BLoCMiddleware extends StateManagementMiddleware { managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); var fileStrategy = - configuration.fileStructureStrategy as FlutterFileStructureStrategy; + configuration.fileStructureStrategy as BLoCFileStructureStrategy; /// Incase of SymbolInstance if (node is PBSharedInstanceIntermediateNode) { @@ -102,7 +101,8 @@ class BLoCMiddleware extends StateManagementMiddleware { } var parentState = getNameOfNode(node); var generalName = parentState.snakeCase; - var parentDirectory = generalName + '_bloc'; + var blocDirectory = + p.join(fileStrategy.RELATIVE_BLOC_PATH, '${generalName}_bloc'); var states = [node]; var stateBuffer = StringBuffer(); @@ -132,7 +132,7 @@ class BLoCMiddleware extends StateManagementMiddleware { 'STATE${node.currentContext.tree.UUID}', '${generalName}_state', stateBuffer.toString(), - relativePath: parentDirectory)); + symbolPath: blocDirectory)); /// Creates map page mapBuffer.write(_makeStateToWidgetFunction(node)); @@ -143,7 +143,7 @@ class BLoCMiddleware extends StateManagementMiddleware { 'MAP${node.currentContext.tree.UUID}', '${generalName}_map', mapBuffer.toString(), - relativePath: parentDirectory)); + symbolPath: blocDirectory)); /// Creates cubit page managerData.addImport(FlutterImport('meta.dart', 'meta')); @@ -154,7 +154,17 @@ class BLoCMiddleware extends StateManagementMiddleware { parentState, node.name, ), - relativePath: parentDirectory)); + symbolPath: blocDirectory)); + + // Generate node's states' view pages + node.auxiliaryData?.stateGraph?.states?.forEach((state) { + fileStrategy.commandCreated(WriteSymbolCommand( + state.variation.node.currentContext.tree.UUID, + state.variation.node.name.snakeCase, + generationManager.generate(state.variation.node), + relativePath: generalName, //Generate view files separately + )); + }); return Future.value(null); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart index 0631d09a..41e5f26a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart @@ -3,6 +3,8 @@ import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart' import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; class BLoCFileStructureStrategy extends FileStructureStrategy { + final RELATIVE_BLOC_PATH = 'lib/blocs'; + BLoCFileStructureStrategy( String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) : super(genProjectPath, pageWriter, pbProject); diff --git a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart index 908963b5..1f3732e1 100644 --- a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/bloc_middleware.dart'; -import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:quick_log/quick_log.dart'; @@ -8,14 +8,14 @@ class BLoCGenerationConfiguration extends GenerationConfiguration { @override Future setUpConfiguration(pbProject) async { + await super.setUpConfiguration(pbProject); logger = Logger('BLoC'); logger.info( 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); - fileStructureStrategy = FlutterFileStructureStrategy( + fileStructureStrategy = BLoCFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject); registerMiddleware(BLoCMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); - return super.setUpConfiguration(pbProject); } } From 549061db4560f6d494e02b7003ccf1933cf85bf8 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 14 Jun 2021 15:41:48 -0600 Subject: [PATCH 206/404] Remove constraints from cubit initializer --- .../generators/middleware/state_management/bloc_middleware.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 9490e9c9..bfe332f9 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -31,7 +31,7 @@ class BLoCMiddleware extends StateManagementMiddleware { part '${snakeName}_state.dart'; class ${pascalName}Cubit extends Cubit<${pascalName}State> { - ${pascalName}Cubit(this.constraints) : super(${initialStateName.pascalCase}State()); + ${pascalName}Cubit() : super(${initialStateName.pascalCase}State()); void onGesture(){ // TODO: Populate onGesture method From fe0a29641cff3dbc53924c2e75ea522fe44d2031 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 14 Jun 2021 16:26:37 -0600 Subject: [PATCH 207/404] Generate view pages successfully. Co-authored-by: Bryan Figueroa --- .../state_management/bloc_middleware.dart | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index bfe332f9..27158663 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/generation/generators/value_objects/generator_adap import 'package:parabeac_core/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; import '../../pb_generation_manager.dart'; @@ -62,7 +63,6 @@ class BLoCMiddleware extends StateManagementMiddleware { var managerData = node.managerData; node.currentContext.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); - managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); var fileStrategy = configuration.fileStructureStrategy as BLoCFileStructureStrategy; @@ -74,9 +74,7 @@ class BLoCMiddleware extends StateManagementMiddleware { if (node.generator is! StringGeneratorAdapter) { var nameWithCubit = '${generalStateName.pascalCase}Cubit'; var nameWithState = '${generalStateName.pascalCase}State'; - var master = - PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); - var namewithToWidget = '${master.name.camelCase}StateToWidget'; + var namewithToWidget = '${generalStateName}StateToWidget'; node.generator = StringGeneratorAdapter(''' LayoutBuilder( @@ -115,12 +113,18 @@ class BLoCMiddleware extends StateManagementMiddleware { var isFirst = true; states.forEach((element) { element.currentContext.tree.data = node.managerData; + + // Creating copy of template to generate State + var templateCopy = element.generator.templateStrategy; + element.generator.templateStrategy = BLoCStateTemplateStrategy( isFirst: isFirst, abstractClassName: parentState, ); stateBuffer.write(generationManager.generate(element)); + element.generator.templateStrategy = templateCopy; + isFirst = false; }); @@ -140,13 +144,31 @@ class BLoCMiddleware extends StateManagementMiddleware { /// modified the [UUID] to prevent adding import because the event is /// using `part of` syntax already when importing the bloc - 'MAP${node.currentContext.tree.UUID}', + '${node.currentContext.tree.UUID}', '${generalName}_map', mapBuffer.toString(), symbolPath: blocDirectory)); + // Generate node's states' view pages + node.auxiliaryData?.stateGraph?.states?.forEach((state) { + fileStrategy.commandCreated(WriteSymbolCommand( + 'SYMBOL${state.variation.node.currentContext.tree.UUID}', + state.variation.node.name.snakeCase, + generationManager.generate(state.variation.node), + relativePath: generalName, //Generate view files separately + )); + }); + + // Generate default node's view page + fileStrategy.commandCreated(WriteSymbolCommand( + 'SYMBOL${node.currentContext.tree.UUID}', + node.name.snakeCase, + generationManager.generate(node), + relativePath: generalName)); + /// Creates cubit page managerData.addImport(FlutterImport('meta.dart', 'meta')); + managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); fileStrategy.commandCreated(WriteSymbolCommand( node.currentContext.tree.UUID, '${generalName}_cubit', @@ -156,16 +178,6 @@ class BLoCMiddleware extends StateManagementMiddleware { ), symbolPath: blocDirectory)); - // Generate node's states' view pages - node.auxiliaryData?.stateGraph?.states?.forEach((state) { - fileStrategy.commandCreated(WriteSymbolCommand( - state.variation.node.currentContext.tree.UUID, - state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node), - relativePath: generalName, //Generate view files separately - )); - }); - return Future.value(null); } @@ -175,11 +187,9 @@ class BLoCMiddleware extends StateManagementMiddleware { element.name.substring(0, element.name.lastIndexOf('/')).snakeCase; stateBuffer.write("import 'package:flutter/material.dart';"); // TODO: replace dynamically - stateBuffer.write( - "import 'package:temp/widgets/${elementName}_bloc/${elementName}_cubit.dart';"); stateBuffer.write( - 'Widget ${element.name.camelCase}StateToWidget( ${element.name.pascalCase}State state, BoxConstraints constraints) {'); + 'Widget ${elementName}StateToWidget( ${elementName.pascalCase}State state, BoxConstraints constraints) {'); for (var i = 0; i < element.auxiliaryData.stateGraph.states.length; i++) { if (i == 0) { stateBuffer.write(_getStateLogic( From 0c5a597a1b4acd7872da2cc6a33f9444e1077403 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 14 Jun 2021 16:59:46 -0600 Subject: [PATCH 208/404] Fixed imports for bloc files --- .../state_management/bloc_middleware.dart | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 27158663..c0b01cb1 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; @@ -71,10 +72,11 @@ class BLoCMiddleware extends StateManagementMiddleware { if (node is PBSharedInstanceIntermediateNode) { var generalStateName = node.functionCallName .substring(0, node.functionCallName.lastIndexOf('/')); + managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); if (node.generator is! StringGeneratorAdapter) { var nameWithCubit = '${generalStateName.pascalCase}Cubit'; var nameWithState = '${generalStateName.pascalCase}State'; - var namewithToWidget = '${generalStateName}StateToWidget'; + var namewithToWidget = '${generalStateName.camelCase}StateToWidget'; node.generator = StringGeneratorAdapter(''' LayoutBuilder( @@ -183,29 +185,32 @@ class BLoCMiddleware extends StateManagementMiddleware { String _makeStateToWidgetFunction(PBIntermediateNode element) { var stateBuffer = StringBuffer(); + var importBuffer = StringBuffer(); var elementName = element.name.substring(0, element.name.lastIndexOf('/')).snakeCase; - stateBuffer.write("import 'package:flutter/material.dart';"); - // TODO: replace dynamically + importBuffer.write("import 'package:flutter/material.dart'; \n"); + importBuffer.write( + "import 'package:${MainInfo().projectName}/blocs/${elementName}_bloc/${elementName}_cubit.dart';\n"); stateBuffer.write( - 'Widget ${elementName}StateToWidget( ${elementName.pascalCase}State state, BoxConstraints constraints) {'); + 'Widget ${elementName.camelCase}StateToWidget( ${elementName.pascalCase}State state, BoxConstraints constraints) {'); for (var i = 0; i < element.auxiliaryData.stateGraph.states.length; i++) { + var node = element.auxiliaryData.stateGraph.states[i].variation.node; if (i == 0) { - stateBuffer.write(_getStateLogic( - element.auxiliaryData.stateGraph.states[i].variation.node, 'if')); + stateBuffer.write(_getStateLogic(node, 'if')); } else { { - stateBuffer.write(_getStateLogic( - element.auxiliaryData.stateGraph.states[i].variation.node, - 'else if')); + stateBuffer.write(_getStateLogic(node, 'else if')); } } + importBuffer.write( + "import 'package:${MainInfo().projectName}/widgets/${elementName}/${node.name.snakeCase}.dart'; \n"); } - + importBuffer.write( + "import 'package:${MainInfo().projectName}/widgets/${elementName}/${element.name.snakeCase}.dart'; \n"); stateBuffer.write('return ${element.name.pascalCase}(constraints); \n }'); - return stateBuffer.toString(); + return importBuffer.toString() + stateBuffer.toString(); } String _getStateLogic(PBIntermediateNode node, String statement) { From 859033cf3becdd43553b3ca1dedb27d06d9c975b Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 15 Jun 2021 15:36:07 -0600 Subject: [PATCH 209/404] Corrected names on orientations and multiplatform screens --- .../generators/middleware/command_gen_middleware.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/generation/generators/middleware/command_gen_middleware.dart b/lib/generation/generators/middleware/command_gen_middleware.dart index 784cdea7..aac26dfa 100644 --- a/lib/generation/generators/middleware/command_gen_middleware.dart +++ b/lib/generation/generators/middleware/command_gen_middleware.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/generation/generators/value_objects/generation_con import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; +import 'package:recase/recase.dart'; class CommandGenMiddleware extends Middleware with PBPlatformOrientationGeneration { @@ -40,7 +41,7 @@ class CommandGenMiddleware extends Middleware tree.UUID, tree.rootNode.currentContext.tree.data.platform, tree.identifier, - tree.rootNode.name, + tree.rootNode.name.snakeCase, generationManager.generate(tree.rootNode), ); } else if (tree.isScreen()) { From 8dfb763a7df6c7454b2695149ef56baea0649682 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 15 Jun 2021 15:56:04 -0600 Subject: [PATCH 210/404] Corrected class name for main --- .../generation_configuration/pb_generation_configuration.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 71ecd7ae..ec22be2c 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -176,7 +176,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { if (rootName.contains('_')) { rootName = rootName.split('_')[0].pascalCase; } - var currentMap = poLinker.getPlatformOrientationData(rootName); + var currentMap = poLinker.getPlatformOrientationData(rootName.snakeCase); var className = [rootName.pascalCase, '']; if (currentMap.length > 1) { className[0] += 'PlatformBuilder'; From 0a94742bc151c0d92603f29e040845cc0aee8e61 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 15 Jun 2021 21:47:53 -0600 Subject: [PATCH 211/404] WIP decoupled some of the commands ran when creating a project, enabling the project creation at the beginning of the project. --- .../flutter_project_builder.dart | 148 ++++++++---------- .../pb_generation_configuration.dart | 4 +- 2 files changed, 68 insertions(+), 84 deletions(-) diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index 95e62126..b1562748 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -11,6 +11,7 @@ import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_linker.dart'; import 'package:quick_log/quick_log.dart'; +import 'package:tuple/tuple.dart'; // String pathToFlutterProject = '${MainInfo().outputPath}/temp/'; @@ -24,24 +25,14 @@ import 'package:quick_log/quick_log.dart'; /// For example, if the Flutter project were to be `my/awesome/path/FlutterProject,` /// the [flutterDir] would be `my/awesome/path,` while the project name is `FlutterProject.` class FlutterProjectBuilder { + /// The [PBProject] that will be converted into a Flutter project. PBProject project; - Logger log; + /// Logger that prints consoles informatio + static Logger log; PBPageWriter pageWriter; - /// The path of the directory where the [project] is going to be generated at. - final String flutterDir; - - /// The name that will be used for the generation of the [project] - /// - /// If no [projectName] is provided, the [PBProject.projectName] will - /// be used as the default value. - String projectName; - - /// The absolute path for the generated [project] - String genProjectAbsPath; - ///The [GenerationConfiguration] that is going to be use in the generation of the code /// ///This is going to be defaulted to [GenerationConfiguration] if nothing else is specified. @@ -51,69 +42,81 @@ class FlutterProjectBuilder { this.generationConfiguration, { this.project, this.pageWriter, - this.projectName, - this.genProjectAbsPath, - this.flutterDir, }) { log = Logger(runtimeType.toString()); - projectName ??= project.projectName; - genProjectAbsPath ??= p.join(flutterDir, projectName); - - if (genProjectAbsPath == null) { - log.error( - '[genProjectAbsPath] is null, caused by not providing both [projectName] & [flutterDir] or providing [genProjectAbsPath]'); - throw NullThrownError(); - } - generationConfiguration.pageWriter = pageWriter; } - Future convertToFlutterProject({List rawImages}) async { - try { - var createResult = Process.runSync('flutter', ['create', projectName], - workingDirectory: MainInfo().outputPath); - if (createResult.stderr != null && createResult.stderr.isNotEmpty) { - log.error(createResult.stderr); - } else { - log.info(createResult.stdout); + /// Creating a Flutter project within the [projectDir] with the name of [flutterProjectName]. + /// + /// Make sure that the [projectDir] does not contain the [flutterProjectName], it should only be + /// the directory where the flutter project is going to be generated. Finally, the function + /// is going to return a [Tuple2], [Tuple2.item1] being the path of the [flutterProjectName] and + /// [Tuple2.item2] being the [ProcessResult.stdout] or [ProcessResult.stderr] depending + /// on the [ProcessResult.exitCode]. If the [createAssetsDir] is `true`, its going to create + /// the [assetsDir] within the flutter project. + static Future createFlutterProject(String flutterProjectName, + {String projectDir, + bool createAssetsDir = true, + String assetsDir = 'assets/images/'}) { + return Process.run('flutter', ['create', flutterProjectName], + workingDirectory: projectDir, runInShell: true) + .then((result) => Tuple2(p.join(projectDir, flutterProjectName), + result.exitCode == 2 ? result.stderr : result.stdout)) + .then((tuple) async { + if (createAssetsDir) { + await Directory(p.join(tuple.item1, assetsDir)) + .create(recursive: true) + .catchError((e) { + log.error(e.toString()); + }); } - } catch (error, stackTrace) { - await MainInfo().sentry.captureException( - exception: error, - stackTrace: stackTrace, - ); - log.error(error.toString()); - } + return tuple; + }).catchError((onError) { + MainInfo().captureException(onError); + log.error(onError.toString()); + }); + } - await Directory(p.join(genProjectAbsPath, 'assets/images')) - .create(recursive: true) - .catchError((e) { - log.error(e.toString()); + /// Formatting the flutter project that is at [projectPath]. + /// + /// The formatter is going to be running within `[projectPath]bin/*`, + /// `[projectPath]lib/*`, and `[projectPath]test/*` by using `dart format`. + /// There is an option to set to set the current working directory of as [projectDir], + static Future formatProject(String projectPath, {String projectDir}) { + return Process.run( + 'dart', + [ + 'format', + p.join(projectPath, 'bin'), + p.join(projectPath, 'lib'), + p.join(projectPath, 'test') + ], + workingDirectory: projectDir, + runInShell: true) + .then((result) => result.exitCode == 2 ? result.stderr : result.stdout) + .catchError((error) { + MainInfo().captureException(error); + log.error(error.toString()); }); + } + Future genProjectFiles(String genProjectPath, + {List rawImages}) async { + if (MainInfo().figmaProjectID != null && MainInfo().figmaProjectID.isNotEmpty) { log.info('Processing remaining images...'); await FigmaAssetProcessor().processImageQueue(); } - Process.runSync( - p.join(MainInfo().cwd.path, - '/lib/generation/helperScripts/shell-proxy.sh'), - [ - 'mv ${p.join('./pngs', '*')} ${p.join(genProjectAbsPath, 'assets/images/')}' - ], - runInShell: true, - environment: Platform.environment, - workingDirectory: MainInfo().outputPath); - // Add all images if (rawImages != null) { for (var image in rawImages) { if (image.name != null) { var f = File(p.setExtension( - p.join(genProjectAbsPath, 'assets/images/', + p.join(genProjectPath, 'assets/images/', image.name.replaceAll(' ', '')), '.png')); f.writeAsBytesSync(image.content); @@ -126,14 +129,13 @@ class FlutterProjectBuilder { project.sharedStyles.isNotEmpty && MainInfo().exportStyles) { try { - Directory(p.join(genProjectAbsPath, 'lib/document/')) + Directory(p.join(genProjectPath, 'lib/document/')) .createSync(recursive: true); - WriteStyleClasses(genProjectAbsPath); + WriteStyleClasses(genProjectPath); - var s = - File(p.join(genProjectAbsPath, 'lib/document/shared_props.g.dart')) - .openWrite(mode: FileMode.write, encoding: utf8); + var s = File(p.join(genProjectPath, 'lib/document/shared_props.g.dart')) + .openWrite(mode: FileMode.write, encoding: utf8); s.write('''${FlutterImport('dart:ui', null)} ${FlutterImport('flutter/material.dart', null)} @@ -153,35 +155,15 @@ class FlutterProjectBuilder { await generationConfiguration .generatePlatformAndOrientationInstance(project); - Process.runSync( - p.join(MainInfo().cwd.path, - '/lib/generation/helperScripts/shell-proxy.sh'), - ['rm -rf .dart_tool/build'], - runInShell: true, - environment: Platform.environment, - workingDirectory: MainInfo().outputPath); - // Remove pngs folder Process.runSync( - p.join(MainInfo().cwd.path, - '/lib/generation/helperScripts/shell-proxy.sh'), - ['rm -rf ${p.join(MainInfo().outputPath, '/pngs')}'], + 'rm', + ['-rf', '.dart_tool/build'], runInShell: true, environment: Platform.environment, workingDirectory: MainInfo().outputPath); - log.info( - Process.runSync( - 'dart', - [ - 'format', - '${p.join(genProjectAbsPath, 'bin')}', - '${p.join(genProjectAbsPath, 'lib')}', - '${p.join(genProjectAbsPath, 'test')}' - ], - workingDirectory: MainInfo().outputPath) - .stdout, - ); + await formatProject(genProjectPath, projectDir: MainInfo().outputPath); } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 71ecd7ae..a47a0d84 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/command_gen_middleware.dart'; @@ -106,6 +107,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ///Generates the [PBIntermediateTree]s within the [pb_project] Future generateProject(PBProject pb_project) async { + var processInfo = MainInfo(); _head = CommandGenMiddleware( generationManager, this, _importProcessor, pb_project.projectName); @@ -129,7 +131,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { commandQueue.clear(); await generateTrees(pb_project.forest, pb_project); - await _commitDependencies(pb_project.projectAbsPath); + await _commitDependencies(processInfo.genProjectPath); } void registerMiddleware(Middleware middleware) { From 77fdfe0f3b202ecca0a4172287ea4c97ea433848 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 15 Jun 2021 21:50:03 -0600 Subject: [PATCH 212/404] WIP aggregated and added new attributes to the MainInfo Singleton, one of which is the png path. This allows for the creation of the PNGs inside of the correct spot from the beginning (eliminating the need to have them in temp folder then moving them). --- lib/controllers/main_info.dart | 80 +++++++++++++++++-- lib/design_logic/boolean_operation.dart | 2 +- lib/design_logic/image.dart | 2 +- lib/design_logic/vector.dart | 2 +- .../figma/helper/figma_asset_processor.dart | 2 +- .../sketch/helper/sketch_asset_processor.dart | 4 +- lib/input/sketch/services/input_design.dart | 4 +- .../helpers/pb_configuration.dart | 2 - .../helpers/pb_image_reference_storage.dart | 2 +- 9 files changed, 84 insertions(+), 16 deletions(-) diff --git a/lib/controllers/main_info.dart b/lib/controllers/main_info.dart index 75bfae95..770010b1 100644 --- a/lib/controllers/main_info.dart +++ b/lib/controllers/main_info.dart @@ -2,21 +2,56 @@ import 'dart:io'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:sentry/sentry.dart'; +import 'package:path/path.dart' as p; class MainInfo { static final MainInfo _singleton = MainInfo._internal(); - SentryClient sentry; + + final SentryClient _sentry = SentryClient( + dsn: + 'https://6e011ce0d8cd4b7fb0ff284a23c5cb37@o433482.ingest.sentry.io/5388747'); - /// Path representing where the output of parabeac-core will be produced - String outputPath; + @Deprecated('Use the function handle error for logging and capturing the error') + SentryClient get sentry => _sentry; + + /// Path representing where the output of parabeac-core will be produced to. + /// + /// First, we are going to check the if any path was passed as a flag to [outputPath], + /// then check in the [configuration] to see if there are any paths saved ([PBConfiguration.outputDirPath]). + String _outputPath; + String get outputPath => _outputPath ?? configuration?.outputDirPath; + set outputPath(String path) => _outputPath = _validatePath(path); /// Path to the user's sketch file - String sketchPath; + String _designFilePath; + String get designFilePath => _designFilePath; + set designFilePath(String path) => _designFilePath = _validatePath(path); + + /// Absolute path of where the flutter project is going to be generating at. + /// + /// If its PBC is generating the flutter project, its going to [p.join] the + /// [outputPath] and the [projectName]. Meaning the the code should be generated + /// into the flutter directory. Otherwise, the code is going to be generated within the directory + /// specified in the [outputPath]. + String get genProjectPath { + return p.join(outputPath, projectName ?? ''); + } String platform; /// Current working directory; contains the path from where the script was called Directory cwd; + + /// The path of where the PBDL file is at. + String _pbdlPath; + String get pbdlPath => _pbdlPath; + set pbdlPath(String path) => _pbdlPath = _validatePath(path); + + /// Specific [configuration] items specified by the user, or attributes that + /// are derived straight from the configuration items that the user provided. + /// + /// For example, some of the configuration that are derived is the [GenerationConfiguration], + /// based on the JSON file the user used for configuration. PBConfiguration configuration; // the type of configuration you want to set, 'default' is default type. @@ -26,7 +61,9 @@ class MainInfo { String deviceId; /// Name of the project - String projectName; + String _projectName; + String get projectName => _projectName ?? configuration?.projectName; + set projectName(String name) => _projectName = name; /// API needed to do API callls String figmaKey; @@ -37,11 +74,44 @@ class MainInfo { /// Boolean that indicates whether a `styles` document is created. bool exportStyles; + /// Exporting the PBDL JSON file instead of generating the actual Flutter code. + bool exportPBDL; + Map pbdf; + /// Type of [DesignType] that is being processed by the current process of + /// Parabeac Core. + DesignType designType; + + /// Where the assets are going to be generating through the process. + String _pngPath; + String get pngPath => _pngPath; + set pngPath(String path) => _pngPath = _validatePath(path ?? _defaultPNGPath); + + String get _defaultPNGPath => p.join(outputPath ?? cwd, 'pngs'); + + /// Checks if the [path] is `null`, if its not, it will [p.absolute] and finally, + /// run [p.normalize] on the [path]. + /// + /// This is primarly to enforce absolute and correct paths in the [MainInfo] + String _validatePath(String path) { + if (path == null) { + return path; + } + return p.normalize(p.absolute(path)); + } + + /// Decoupling the exception capture client from the services that report the [exception] + void captureException(exception) { + _sentry.captureException(exception: exception); + } + factory MainInfo() { return _singleton; } MainInfo._internal(); } + +/// The type of design that is being processed by Parabeac Core. +enum DesignType { SKETCH, FIGMA, PBDL, UNKNOWN } diff --git a/lib/design_logic/boolean_operation.dart b/lib/design_logic/boolean_operation.dart index 8b03cc13..d17b6fdf 100644 --- a/lib/design_logic/boolean_operation.dart +++ b/lib/design_logic/boolean_operation.dart @@ -34,7 +34,7 @@ class BooleanOperation implements DesignNodeFactory, DesignNode { Future interpretNode(PBContext currentContext) async { var img = await AzureAssetService().downloadImage(UUID); var path = - p.join(MainInfo().outputPath, 'pngs', '$UUID.png'.replaceAll(':', '_')); + p.join(MainInfo().pngPath, '$UUID.png'.replaceAll(':', '_')); var file = File(path)..createSync(recursive: true); file.writeAsBytesSync(img); diff --git a/lib/design_logic/image.dart b/lib/design_logic/image.dart index d6d1d5a5..a7fc0bbe 100644 --- a/lib/design_logic/image.dart +++ b/lib/design_logic/image.dart @@ -95,7 +95,7 @@ class Image extends DesignElement implements DesignNodeFactory, DesignNode { @override Future interpretNode(PBContext currentContext) async { var pngsPath = - p.join(MainInfo().outputPath, 'pngs', '$UUID.png'.replaceAll(':', '_')); + p.join(MainInfo().pngPath, '$UUID.png'.replaceAll(':', '_')); try { var img = await AzureAssetService().downloadImage(UUID); var file = File(pngsPath)..createSync(recursive: true); diff --git a/lib/design_logic/vector.dart b/lib/design_logic/vector.dart index 14d537a8..694c7765 100644 --- a/lib/design_logic/vector.dart +++ b/lib/design_logic/vector.dart @@ -108,7 +108,7 @@ class Vector implements DesignNodeFactory, DesignNode, Image { imageReference = AssetProcessingService.getImageName(UUID); var pngsPath = - p.join(MainInfo().outputPath, 'pngs', '$UUID.png'.replaceAll(':', '_')); + p.join(MainInfo().pngPath, '$UUID.png'.replaceAll(':', '_')); var file = File(pngsPath)..createSync(recursive: true); file.writeAsBytesSync(img); return Future.value( diff --git a/lib/input/figma/helper/figma_asset_processor.dart b/lib/input/figma/helper/figma_asset_processor.dart index 83a17363..670a608f 100644 --- a/lib/input/figma/helper/figma_asset_processor.dart +++ b/lib/input/figma/helper/figma_asset_processor.dart @@ -86,7 +86,7 @@ class FigmaAssetProcessor extends AssetProcessingService { } if (writeAsFile) { - var pngsPath = p.join(MainInfo().outputPath, 'pngs', + var pngsPath = p.join(MainInfo().pngPath, '${entry.key}.png'.replaceAll(':', '_')); var file = File(pngsPath)..createSync(recursive: true); file.writeAsBytesSync(imageRes.bodyBytes); diff --git a/lib/input/sketch/helper/sketch_asset_processor.dart b/lib/input/sketch/helper/sketch_asset_processor.dart index 187447dc..ac0820d8 100644 --- a/lib/input/sketch/helper/sketch_asset_processor.dart +++ b/lib/input/sketch/helper/sketch_asset_processor.dart @@ -33,12 +33,12 @@ class SketchAssetProcessor extends AssetProcessingService { 'uuid': uuid, 'width': width, 'height': height, - 'blob': getBlobName(MainInfo().sketchPath), + 'blob': getBlobName(MainInfo().designFilePath), 'container': 'design-file' } : { 'uuid': uuid, - 'path': MainInfo().sketchPath, + 'path': MainInfo().designFilePath, 'width': width, 'height': height }; diff --git a/lib/input/sketch/services/input_design.dart b/lib/input/sketch/services/input_design.dart index bb315e46..60f75e3b 100644 --- a/lib/input/sketch/services/input_design.dart +++ b/lib/input/sketch/services/input_design.dart @@ -8,7 +8,7 @@ import 'package:path/path.dart' as p; /// Takes Initial Design File and puts it into a tree in object format. /// Currently only supports Sketch Files -///Class used to process the contents of a sketch file +/// Class used to process the contents of a sketch file class InputDesignService { final String pathToFile; final String IMAGE_DIR_NAME = 'images/'; @@ -44,7 +44,7 @@ class InputDesignService { ///Getting the images in the sketch file and adding them to the png folder. void setImageDir() { ///Creating the pngs folder, if it's already not there. - var pngsPath = p.join(MainInfo().outputPath, 'pngs'); + var pngsPath = p.join(MainInfo().pngPath); Directory(pngsPath).createSync(recursive: true); for (final file in archive) { final fileName = file.name; diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.dart b/lib/interpret_and_optimize/helpers/pb_configuration.dart index e97c6ecd..f5413dad 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.dart @@ -28,8 +28,6 @@ class PBConfiguration { String outputDirPath; - String get genProjectPath => p.join(outputDirPath, projectName); - @JsonKey(defaultValue: 'Material') final String widgetStyle; diff --git a/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart b/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart index 178d9d69..df24074e 100644 --- a/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart +++ b/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart @@ -25,7 +25,7 @@ class ImageReferenceStorage { /// Adds the reference to the image and writes the png to the assets folder. /// Returns true if the image was written successfully, false otherwise bool addReferenceAndWrite(String name, String path, Uint8List image) { - var imgPath = p.join(MainInfo().outputPath, 'pngs', '$name.png'); + var imgPath = p.join(MainInfo().pngPath, '$name.png'); if (image == null && File('${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png') .existsSync() && From 4a145447179de033438f531082a8dfa8b68e1b3d Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 15 Jun 2021 21:51:30 -0600 Subject: [PATCH 213/404] WIP decoupled the controllers from the main.dart file. Where depending on the identifier, the correct controller should be initialized, configured, and start converting the project. --- lib/controllers/controller.dart | 67 ++++-- lib/controllers/design_controller.dart | 26 +-- lib/controllers/figma_controller.dart | 49 +++-- lib/controllers/sketch_controller.dart | 83 ++++++-- lib/main.dart | 282 +++++++++---------------- 5 files changed, 244 insertions(+), 263 deletions(-) diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index b6b63035..2aa2023f 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -4,45 +4,78 @@ import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.da import 'package:parabeac_core/input/helper/asset_processing_service.dart'; import 'package:parabeac_core/input/helper/azure_asset_service.dart'; import 'package:parabeac_core/input/helper/design_project.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:quick_log/quick_log.dart'; import 'dart:convert'; import 'dart:io'; +import 'package:meta/meta.dart'; import 'main_info.dart'; +import 'package:path/path.dart' as p; abstract class Controller { - ///SERVICE - var log = Logger('Controller'); + /// Represents an identifier for the current [Controller] at runtime. + /// + /// The main way of using this is to identify what [Controller] is going to be + /// used based on the [designType] within the `main.dart` file + DesignType get designType; - Controller(); + var log; + + Controller() { + log = Logger(runtimeType.toString()); + } + + /// Gathering all the necessary information for the [Controller] to function + /// properly + /// + /// Most, if not all, of the information will come from the [MainInfo] class. + Future setup() { + var processInfo = MainInfo(); + + /// This is currently a workaround for PB-Nest. This + /// code usually was in the `main.dart`, however, I aggregated all + /// the calls in the default [setup] method for the [Controller] + if (processInfo.pbdlPath != null) { + var pbdl = File(processInfo.pbdlPath).readAsStringSync(); + processInfo.pbdf = json.decode(pbdl); + } + } + + @protected + + /// Mainly used by the subclasses to convert the [designProject] to flutter code. + /// + /// There is a seperation of the methods because some of the [Controller]s need + /// to generate the [designProject] based on the parameters pased to + void convert(DesignProject designProject, + [AssetProcessingService apService]) async { + var processInfo = MainInfo(); + var configuration = processInfo.configuration; - void convertFile( - var fileAbsPath, - var projectPath, - PBConfiguration configuration, { - bool jsonOnly = false, - DesignProject designProject, - AssetProcessingService apService, - }) async { /// IN CASE OF JSON ONLY - if (jsonOnly) { + if (processInfo.exportPBDL) { return stopAndToJson(designProject, apService); } - Interpret().init(projectPath, configuration); + var projectGenFuture = await FlutterProjectBuilder.createFlutterProject( + processInfo.projectName, + projectDir: processInfo.outputPath); + + Interpret().init(processInfo.genProjectPath, configuration); var pbProject = await Interpret().interpretAndOptimize( - designProject, configuration.projectName, configuration.genProjectPath); + designProject, processInfo.projectName, processInfo.genProjectPath); var fpb = FlutterProjectBuilder( MainInfo().configuration.generationConfiguration, project: pbProject, - genProjectAbsPath: configuration.genProjectPath, pageWriter: PBFlutterWriter()); - await fpb.convertToFlutterProject(); + await fpb.genProjectFiles(projectGenFuture.item1); } + void convertFile( + {AssetProcessingService apService, DesignProject designProject}); + /// Method that returns the given path and ensures /// it ends with a / String verifyPath(String path) { diff --git a/lib/controllers/design_controller.dart b/lib/controllers/design_controller.dart index 8192eeb2..071ddc30 100644 --- a/lib/controllers/design_controller.dart +++ b/lib/controllers/design_controller.dart @@ -1,35 +1,27 @@ +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/input/helper/asset_processing_service.dart'; import 'package:parabeac_core/input/helper/azure_asset_service.dart'; import 'package:parabeac_core/input/helper/design_project.dart'; -import 'package:quick_log/quick_log.dart'; import 'controller.dart'; class DesignController extends Controller { @override - var log = Logger('FigmaController'); - - DesignController(); + DesignType get designType => DesignType.PBDL; @override - void convertFile( - var pbdf, - var outputPath, - configuration, { - bool jsonOnly = false, + void convertFile({ DesignProject designProject, AssetProcessingService apService, }) async { - var designProject = generateDesignProject(pbdf, outputPath); + var pbdf = MainInfo().pbdf; + if (pbdf == null) { + throw Error(); //todo: throw correct error + } + designProject ??= generateDesignProject(pbdf, MainInfo().genProjectPath); AzureAssetService().projectUUID = pbdf['id']; - super.convertFile( - pbdf, - outputPath, - configuration, - designProject: designProject, - jsonOnly: jsonOnly, - ); + super.convert(designProject, apService); } DesignProject generateDesignProject(var pbdf, var proejctName) { diff --git a/lib/controllers/figma_controller.dart b/lib/controllers/figma_controller.dart index 7cf94d6d..7af33949 100644 --- a/lib/controllers/figma_controller.dart +++ b/lib/controllers/figma_controller.dart @@ -2,41 +2,32 @@ import 'package:parabeac_core/controllers/controller.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/input/figma/entities/layers/component.dart'; import 'package:parabeac_core/input/figma/entities/layers/frame.dart'; +import 'package:parabeac_core/input/figma/helper/api_call_service.dart'; +import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/input/figma/helper/figma_project.dart'; import 'package:parabeac_core/input/helper/asset_processing_service.dart'; +import 'package:parabeac_core/input/helper/azure_asset_service.dart'; import 'package:parabeac_core/input/helper/design_project.dart'; -import 'package:quick_log/quick_log.dart'; class FigmaController extends Controller { - ///SERVICE @override - var log = Logger('FigmaController'); - - FigmaController(); + DesignType get designType => DesignType.FIGMA; @override - void convertFile( - var jsonFigma, - var outputPath, - var configuration, { - bool jsonOnly = false, + void convertFile({ DesignProject designProject, AssetProcessingService apService, }) async { - var figmaProject = generateFigmaTree(jsonFigma, outputPath); - - figmaProject = declareScaffolds(figmaProject); - - _sortPages(figmaProject); + var jsonFigma = await _fetchFigmaFile(); + if (jsonFigma == null) { + throw Error(); //todo: find correct error + } + AzureAssetService().projectUUID = MainInfo().figmaProjectID; + designProject ??= generateFigmaTree(jsonFigma, MainInfo().genProjectPath); + designProject = declareScaffolds(designProject); - super.convertFile( - jsonFigma, - outputPath, - configuration, - designProject: figmaProject, - jsonOnly: jsonOnly, - apService: apService, - ); + _sortPages(designProject); + super.convert(designProject, apService ?? FigmaAssetProcessor()); } FigmaProject generateFigmaTree(var jsonFigma, var projectname) { @@ -52,6 +43,10 @@ class FigmaController extends Controller { } } + Future _fetchFigmaFile() => APICallService.makeAPICall( + 'https://api.figma.com/v1/files/${MainInfo().figmaProjectID}', + MainInfo().figmaKey); + /// This method was required for Figma, so we could /// detect which `FigmaFrame` were Scaffolds or Containers FigmaProject declareScaffolds(FigmaProject tree) { @@ -89,4 +84,12 @@ class FigmaController extends Controller { }); }); } + + @override + Future setup() async { + var processInfo = MainInfo(); + if (processInfo.figmaKey == null || processInfo.figmaProjectID == null) { + throw Error(); //todo: place correct error + } + } } diff --git a/lib/controllers/sketch_controller.dart b/lib/controllers/sketch_controller.dart index 5ba88eba..c2f1c01d 100644 --- a/lib/controllers/sketch_controller.dart +++ b/lib/controllers/sketch_controller.dart @@ -1,44 +1,39 @@ +import 'dart:io'; +import 'dart:convert'; + import 'package:parabeac_core/controllers/controller.dart'; import 'package:parabeac_core/input/helper/asset_processing_service.dart'; import 'package:parabeac_core/input/helper/azure_asset_service.dart'; import 'package:parabeac_core/input/helper/design_project.dart'; +import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_project.dart'; import 'package:parabeac_core/input/sketch/services/input_design.dart'; -import 'package:quick_log/quick_log.dart'; import 'main_info.dart'; +import 'package:path/path.dart' as p; class SketchController extends Controller { - ///SERVICE @override - var log = Logger('SketchController'); + DesignType get designType => DesignType.SKETCH; ///Converting the [fileAbsPath] sketch file to flutter @override - void convertFile( - var fileAbsPath, - var projectPath, - configuration, { - bool jsonOnly = false, + void convertFile({ DesignProject designProject, AssetProcessingService apService, }) async { + var processInfo = MainInfo(); + ///INTAKE - var ids = InputDesignService(fileAbsPath, jsonOnly: jsonOnly); - var sketchProject = generateSketchNodeTree( - ids, ids.metaFileJson['pagesAndArtboards'], projectPath); - - AzureAssetService().projectUUID = sketchProject.id; - - super.convertFile( - fileAbsPath, - projectPath, - configuration, - designProject: sketchProject, - jsonOnly: jsonOnly, - apService: apService, - ); + var ids = InputDesignService(processInfo.designFilePath, + jsonOnly: processInfo.exportPBDL); + designProject ??= generateSketchNodeTree( + ids, ids.metaFileJson['pagesAndArtboards'], processInfo.genProjectPath); + + AzureAssetService().projectUUID = designProject.id; + + super.convert(designProject , apService ?? SketchAssetProcessor()); } SketchProject generateSketchNodeTree( @@ -54,4 +49,48 @@ class SketchController extends Controller { return null; } } + + @override + Future setup() async { + var processInfo = MainInfo(); + if (!processInfo.exportPBDL) { + if (!FileSystemEntity.isFileSync(processInfo.designFilePath)) { + throw Error(); + } + InputDesignService(processInfo.designFilePath); + await checkSACVersion(); + } + await super.setup(); + } + + Future checkSACVersion() async { + /// Code is moved from `main.dart` + Process process; + if (!Platform.environment.containsKey('SAC_ENDPOINT')) { + var isSACupToDate = await Process.run( + './pb-scripts/check-git.sh', + [], + workingDirectory: MainInfo().cwd.path, + ); + + if (isSACupToDate.stdout + .contains('Sketch Asset Converter is behind master.')) { + log.warning(isSACupToDate.stdout); + } else { + log.info(isSACupToDate.stdout); + } + + process = await Process.start('npm', ['run', 'prod'], + workingDirectory: + p.join(MainInfo().cwd.path, '/SketchAssetConverter')); + + await for (var event in process.stdout.transform(utf8.decoder)) { + if (event.toLowerCase().contains('server is listening on port')) { + log.fine('Successfully started Sketch Asset Converter'); + break; + } + } + process?.kill(); + } + } } diff --git a/lib/main.dart b/lib/main.dart index d6326a8e..ad6480de 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,11 +4,6 @@ import 'package:parabeac_core/controllers/design_controller.dart'; import 'package:parabeac_core/controllers/figma_controller.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/controllers/sketch_controller.dart'; -import 'package:parabeac_core/input/figma/helper/api_call_service.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; -import 'package:parabeac_core/input/sketch/services/input_design.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; import 'package:quick_log/quick_log.dart'; @@ -16,19 +11,44 @@ import 'package:sentry/sentry.dart'; import 'package:uuid/uuid.dart'; import 'package:http/http.dart' as http; import 'package:args/args.dart'; +import 'controllers/controller.dart'; import 'controllers/main_info.dart'; import 'package:yaml/yaml.dart'; import 'package:path/path.dart' as p; -ArgResults argResults; - +var controllers = [ + FigmaController(), + SketchController(), + DesignController() +]; + +///sets up parser +final parser = ArgParser() + ..addOption('path', + help: 'Path to the design file', valueHelp: 'path', abbr: 'p') + ..addOption('out', help: 'The output path', valueHelp: 'path', abbr: 'o') + ..addOption('project-name', + help: 'The name of the project', abbr: 'n', defaultsTo: 'temp') + ..addOption('config-path', + help: 'Path of the configuration file', + abbr: 'c', + defaultsTo: + '${p.setExtension(p.join('lib/configurations/', 'configurations'), '.json')}') + ..addOption('fig', help: 'The ID of the figma file', abbr: 'f') + ..addOption('figKey', help: 'Your personal API Key', abbr: 'k') + ..addOption( + 'pbdl-in', + help: + 'Takes in a Parabeac Design Logic (PBDL) JSON file and exports it to a project', + ) + ..addFlag('help', + help: 'Displays this help information.', abbr: 'h', negatable: false) + ..addFlag('export-pbdl', + help: 'This flag outputs Parabeac Design Logic (PBDL) in JSON format.') + ..addFlag('exclude-styles', + help: 'If this flag is set, it will exclude output styles document'); void main(List args) async { await checkConfigFile(); - - //Sentry logging initialization - MainInfo().sentry = SentryClient( - dsn: - 'https://6e011ce0d8cd4b7fb0ff284a23c5cb37@o433482.ingest.sentry.io/5388747'); var log = Logger('Main'); var pubspec = File('pubspec.yaml'); await pubspec.readAsString().then((String text) { @@ -39,32 +59,6 @@ void main(List args) async { MainInfo().cwd = Directory.current; - ///sets up parser - final parser = ArgParser() - ..addOption('path', - help: 'Path to the design file', valueHelp: 'path', abbr: 'p') - ..addOption('out', help: 'The output path', valueHelp: 'path', abbr: 'o') - ..addOption('project-name', - help: 'The name of the project', abbr: 'n', defaultsTo: 'temp') - ..addOption('config-path', - help: 'Path of the configuration file', - abbr: 'c', - defaultsTo: - '${p.setExtension(p.join('lib/configurations/', 'configurations'), '.json')}') - ..addOption('fig', help: 'The ID of the figma file', abbr: 'f') - ..addOption('figKey', help: 'Your personal API Key', abbr: 'k') - ..addOption( - 'pbdl-in', - help: - 'Takes in a Parabeac Design Logic (PBDL) JSON file and exports it to a project', - ) - ..addFlag('help', - help: 'Displays this help information.', abbr: 'h', negatable: false) - ..addFlag('export-pbdl', - help: 'This flag outputs Parabeac Design Logic (PBDL) in JSON format.') - ..addFlag('exclude-styles', - help: 'If this flag is set, it will exclude output styles document'); - //error handler using logger package void handleError(String msg) { log.error(msg); @@ -72,171 +66,91 @@ void main(List args) async { exit(2); } - argResults = parser.parse(args); + var argResults = parser.parse(args); - //Check if no args passed or only -h/--help passed + /// Check if no args passed or only -h/--help passed if (argResults['help'] || argResults.arguments.isEmpty) { print(''' ** PARABEAC HELP ** ${parser.usage} '''); exit(0); + } else if (hasTooFewArgs(argResults)) { + handleError( + 'Missing required argument: path to Sketch file or both Figma Key and Project ID.'); + } else if (hasTooManyArgs(argResults)) { + handleError( + 'Too many arguments: Please provide either the path to Sketch file or the Figma File ID and API Key'); } - var configuration = - generateConfiguration(p.normalize(argResults['config-path'])); + collectArguments(argResults); + var processInfo = MainInfo(); + if (processInfo.designType == DesignType.UNKNOWN) { + throw UnsupportedError('We have yet to support this DesignType! '); + } - // Detect platform - MainInfo().platform = Platform.operatingSystem; - configuration.platform = Platform.operatingSystem; + var controller = controllers.firstWhere( + (controller) => controller.designType == processInfo.designType); + await controller.setup(); + controller.convertFile(); + + exitCode = 0; +} - String path = argResults['path']; +/// Populates the corresponding fields of the [MainInfo] object with the +/// corresponding [arguments]. +/// +/// Remember that [MainInfo] is a Singleton, therefore, nothing its going to +/// be return from the function. When you use [MainInfo] again, its going to +/// contain the proper values from [arguments] +void collectArguments(ArgResults arguments) { + var info = MainInfo(); - MainInfo().figmaKey = argResults['figKey']; - MainInfo().figmaProjectID = argResults['fig']; + info.configuration = + generateConfiguration(p.normalize(arguments['config-path'])); - var designType = 'sketch'; - MainInfo().exportStyles = !argResults['exclude-styles']; - var jsonOnly = argResults['export-pbdl']; + /// Detect platform + info.platform = Platform.operatingSystem; - // var configurationPath = argResults['config-path']; - // var configurationType = 'default'; - String projectName = argResults['project-name']; + info.figmaKey = arguments['figKey']; + info.figmaProjectID = arguments['fig']; - // Handle input errors - if (hasTooFewArgs(argResults)) { - handleError( - 'Missing required argument: path to Sketch file or both Figma Key and Project ID.'); - } else if (hasTooManyArgs(argResults)) { - handleError( - 'Too many arguments: Please provide either the path to Sketch file or the Figma File ID and API Key'); - } else if (argResults['figKey'] != null && argResults['fig'] != null) { - designType = 'figma'; - } else if (argResults['path'] != null) { - designType = 'sketch'; - } else if (argResults['pbdl-in'] != null) { - designType = 'pbdl'; + info.designFilePath = arguments['path']; + if (arguments['pbdl-in'] != null) { + info.pbdlPath = arguments['pbdl-in']; } - // Populate `MainInfo()` - - // If outputPath is empty, assume we are outputting to design file path - MainInfo().outputPath = (p.absolute( - p.normalize(argResults['out'] ?? p.dirname(path ?? Directory.current)))); - configuration.outputDirPath = MainInfo().outputPath; - - MainInfo().projectName = projectName; - configuration.projectName = projectName; - MainInfo().configuration = configuration; - - // Create pngs directory - var pngsPath = p.join(MainInfo().outputPath, - (jsonOnly || argResults['pbdl-in'] != null ? '' : 'pngs')); - await Directory(pngsPath).create(recursive: true); - - if (designType == 'sketch') { - if (argResults['pbdl-in'] != null) { - var pbdlPath = argResults['pbdl-in']; - var jsonString = File(pbdlPath).readAsStringSync(); - MainInfo().pbdf = json.decode(jsonString); - } - Process process; - if (!jsonOnly) { - var file = await FileSystemEntity.isFile(path); - var exists = await File(path).exists(); - - if (!file || !exists) { - handleError('$path is not a file'); - } - MainInfo().sketchPath = p.normalize(p.absolute(path)); - InputDesignService(path); - - if (!Platform.environment.containsKey('SAC_ENDPOINT')) { - var isSACupToDate = await Process.run( - './pb-scripts/check-git.sh', - [], - workingDirectory: MainInfo().cwd.path, - ); + info.designType = determineDesignTypeFromArgs(arguments); + info.exportStyles = !arguments['exclude-styles']; + info.projectName ??= arguments['project-name']; + + /// If outputPath is empty, assume we are outputting to design file path + info.outputPath = + arguments['out'] ?? p.dirname(info.designFilePath ?? Directory.current); - if (isSACupToDate.stdout - .contains('Sketch Asset Converter is behind master.')) { - log.warning(isSACupToDate.stdout); - } else { - log.info(isSACupToDate.stdout); - } - - process = await Process.start('npm', ['run', 'prod'], - workingDirectory: MainInfo().cwd.path + '/SketchAssetConverter'); - - await for (var event in process.stdout.transform(utf8.decoder)) { - if (event.toLowerCase().contains('server is listening on port')) { - log.fine('Successfully started Sketch Asset Converter'); - break; - } - } - } - } - - SketchController().convertFile( - path, - MainInfo().outputPath + projectName, - configuration, - jsonOnly: jsonOnly, - apService: SketchAssetProcessor(), - ); - process?.kill(); - } else if (designType == 'xd') { - assert(false, 'We don\'t support Adobe XD.'); - } else if (designType == 'figma') { - if (argResults['pbdl-in'] != null) { - var pbdlPath = argResults['pbdl-in']; - var jsonString = File(pbdlPath).readAsStringSync(); - MainInfo().pbdf = json.decode(jsonString); - } - if (MainInfo().figmaKey == null || MainInfo().figmaKey.isEmpty) { - assert(false, 'Please provided a Figma API key to proceed.'); - } - if (MainInfo().figmaProjectID == null || - MainInfo().figmaProjectID.isEmpty) { - assert(false, 'Please provided a Figma project ID to proceed.'); - } - var jsonOfFigma = await APICallService.makeAPICall( - 'https://api.figma.com/v1/files/${MainInfo().figmaProjectID}', - MainInfo().figmaKey); - - if (jsonOfFigma != null) { - AzureAssetService().projectUUID = MainInfo().figmaProjectID; - // Starts Figma to Object - FigmaController().convertFile( - jsonOfFigma, - MainInfo().outputPath + projectName, - configuration, - jsonOnly: jsonOnly, - apService: FigmaAssetProcessor(), - ); - } else { - log.error('File was not retrieved from Figma.'); - } - } else if (designType == 'pbdl') { - var pbdlPath = argResults['pbdl-in']; - var isFile = FileSystemEntity.isFileSync(pbdlPath); - var exists = File(pbdlPath).existsSync(); - - if (!isFile || !exists) { - handleError('$path is not a file'); - } - - var jsonString = await File(pbdlPath).readAsString(); - - var pbdf = json.decode(jsonString); - - DesignController().convertFile( - pbdf, - MainInfo().outputPath + projectName, - configuration, - ); + info.exportPBDL = arguments['export-pbdl'] ?? false; + + /// In the future when we are generating certain dart files only. + /// At the moment we are only generating in the flutter project. + info.pngPath = p.join(info.genProjectPath, 'assets/images'); +} + +/// Determine the [MainInfo.designType] from the [arguments] +/// +/// If [arguments] include `figKey` or `fig`, that implies that [MainInfo.designType] +/// should be [DesignType.FIGMA]. If there is a `path`, then the [MainInfo.designType] +/// should be [DesignType.SKETCH]. Otherwise, if it includes the flag `pndl-in`, the type +/// is [DesignType.PBDL].Finally, if none of the [DesignType] applies, its going to default +/// to [DesignType.UNKNOWN]. +DesignType determineDesignTypeFromArgs(ArgResults arguments) { + if (arguments['figKey'] != null && arguments['fig'] != null) { + return DesignType.FIGMA; + } else if (arguments['path'] != null) { + return DesignType.SKETCH; + } else if (arguments['pbdl-in'] != null) { + return DesignType.PBDL; } - exitCode = 0; + return DesignType.UNKNOWN; } /// Checks whether a configuration file is made already, From 0ac8a079bdc728ed15ff80f1d339788fb3477773 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 15 Jun 2021 22:02:44 -0600 Subject: [PATCH 214/404] Fixed some of the unit-test that were crash because of the introduction of the png path --- test/lib/input_services/edge_adjacent_detection_test.dart | 2 ++ test/lib/output_services/png_gen_test.dart | 6 +++--- test/lib/output_services/project_builder_test.dart | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/lib/input_services/edge_adjacent_detection_test.dart b/test/lib/input_services/edge_adjacent_detection_test.dart index 70b7c29e..7cfe5093 100644 --- a/test/lib/input_services/edge_adjacent_detection_test.dart +++ b/test/lib/input_services/edge_adjacent_detection_test.dart @@ -28,6 +28,7 @@ void main() { sketchNode = ShapePathMock(); context = ContextMock(); MainInfo().outputPath = ''; + MainInfo().pngPath = ''; when(sketchNode.points).thenReturn([ { @@ -132,6 +133,7 @@ void main() { when(sketchNode.UUID).thenReturn(''); shapePath = InheritedShapePath(sketchNode, 'testName', currentContext: context); + }); test('Detecting Shape', () { diff --git a/test/lib/output_services/png_gen_test.dart b/test/lib/output_services/png_gen_test.dart index a1a25fcf..92b86b3a 100644 --- a/test/lib/output_services/png_gen_test.dart +++ b/test/lib/output_services/png_gen_test.dart @@ -19,7 +19,7 @@ void main() async { group('Local Sketch PNG Testing:', () { setUpAll(() async { - MainInfo().sketchPath = + MainInfo().designFilePath = '${Directory.current.path}/test/assets/parabeac_demo_alt.sketch'; uuids = [ '85D93FCD-5A69-4DAF-AE90-351CD9B64554', // Shape Group @@ -58,7 +58,7 @@ void main() async { group('Github Sketch PNG Testing:', () { setUpAll(() async { - MainInfo().sketchPath = + MainInfo().designFilePath = '${Directory.current.path}/test/assets/parabeac_demo_alt.sketch'; uuids = [ '85D93FCD-5A69-4DAF-AE90-351CD9B64554', // Shape Group @@ -94,7 +94,7 @@ void main() async { await FigmaAssetProcessor().processImageQueue(); for (var uuid in FigmaAssetProcessor().uuidQueue) { expect( - File(p.join(MainInfo().outputPath, 'pngs', + File(p.join(MainInfo().pngPath, '$uuid.png'.replaceAll(':', '_'))) .existsSync(), true); diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index b790a58a..4c1b7db5 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -106,7 +106,7 @@ void main() { when(mockConfig.fileStructureStrategy).thenReturn(fss); projectBuilder = FlutterProjectBuilder(mockConfig, - genProjectAbsPath: Directory.current.path, + // genProjectAbsPath: Directory.current.path, project: project, pageWriter: PBFlutterWriter()); }); @@ -116,7 +116,7 @@ void main() { /// Check that the Dart file was created /// It should be a file named `testingPage` /// Stafefulwidget with a Scaffold and a Container - await projectBuilder.convertToFlutterProject(); + await projectBuilder.genProjectFiles(); }, timeout: Timeout( Duration(minutes: 1), From fa9f10cb64809484f27e1ed6b09e936dadd5ce4d Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 15 Jun 2021 23:29:13 -0600 Subject: [PATCH 215/404] Fixed the attribute that was being accessed from [Directory.current] --- lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index ad6480de..51c42c4c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -126,7 +126,7 @@ void collectArguments(ArgResults arguments) { /// If outputPath is empty, assume we are outputting to design file path info.outputPath = - arguments['out'] ?? p.dirname(info.designFilePath ?? Directory.current); + arguments['out'] ?? p.dirname(info.designFilePath ?? Directory.current.path); info.exportPBDL = arguments['export-pbdl'] ?? false; From c233b03af05239e192fa780fcf2640db50fdb014 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 16 Jun 2021 17:15:12 -0600 Subject: [PATCH 216/404] If platform builder is the new home screen, update main --- .../pb_generation_configuration.dart | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index ec22be2c..c3acac24 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/command_gen_middleware.dart'; @@ -8,6 +9,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; @@ -15,6 +17,7 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -186,7 +189,9 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { return className; } - Future generatePlatformAndOrientationInstance(PBProject mainTree) { + /// Generate platform and orientation instances for all the + /// screens that requireds and change main.dart if need it + void generatePlatformAndOrientationInstance(PBProject mainTree) { var currentMap = poLinker.getWhoNeedsAbstractInstance(); currentMap.forEach((screenName, platformsMap) { @@ -205,14 +210,13 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var newCommand = generatePlatformInstance( platformsMap, screenName, fileStructureStrategy, rawImports); + fileStructureStrategy.commandCreated(newCommand); - if (newCommand != null) { - commandObservers - .forEach((observer) => observer.commandCreated(newCommand)); - } + setMainForPlatform(newCommand, screenName); }); } + /// Gets all the screen imports for the builder Set getPlatformImports(String screenName) { var platformOrientationMap = poLinker.getPlatformOrientationData(screenName); @@ -224,4 +228,32 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { }); return imports; } + + /// This method takes a command and checks if one of its child screens + /// is the home screen for the project, if so modify main + /// to redirect to the proper builder + bool setMainForPlatform(var newCommand, String screenName) { + var platformOrientationMap = + poLinker.getPlatformOrientationData(screenName); + + platformOrientationMap.forEach((key, map) { + map.forEach((key, tree) { + if (tree.rootNode is InheritedScaffold && + (tree.rootNode as InheritedScaffold).isHomeScreen) { + fileStructureStrategy.commandCreated(EntryFileCommand( + entryScreenName: (newCommand as WriteScreenCommand) + .name + .replaceAll('.dart', '') + .pascalCase, + entryScreenImport: _importProcessor + .getFormattedImports(newCommand.UUID, + importMapper: (import) => + FlutterImport(import, MainInfo().projectName)) + .join('\n'))); + return true; + } + }); + }); + return false; + } } From f4d2319ded4b6913e0c1e843f9e4c654150da438 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 16 Jun 2021 21:11:45 -0400 Subject: [PATCH 217/404] Remove commented code, fix typos. --- lib/generation/generators/symbols/pb_instancesym_gen.dart | 2 +- .../services/pb_shared_aggregation_service.dart | 3 --- .../value_objects/pb_symbol_master_params.dart | 4 +--- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 6ded4414..de50ca96 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -32,7 +32,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { buffer.write(' builder: (context, constraints) {\n'); buffer.write(' return '); - // If we are processing master symbol generation grab the master, else grab gab the master of ourselves + // If we are processing master symbol generation grab the master, else grab the master of ourselves var masterSymbol = generatorContext.masterNode ?? PBSymbolStorage().getSharedMasterNodeBySymbolID(source.SYMBOL_ID); diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index f08641b9..3f0f0177 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -71,9 +71,6 @@ class PBSharedInterAggregationService { log.warning('UUID: ${targetUUID} not found in searchNodeByUUID'); } } - - //sharedMasterNode.overridableProperties - // .removeWhere((prop) => prop == null || prop.value == null); } ///Its going to check the [PBSharedInstanceIntermediateNode]s and the [PBSharedMasterNode]s that are coming through diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart index 7c86bebe..ca5727b2 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart @@ -30,9 +30,7 @@ class PBSymbolMasterParameter extends PBVisualIntermediateNode this.bottomRightX, this.bottomRightY, {this.context}) - : super(Point(0, 0), Point(0, 0), context, name) { - - } + : super(Point(0, 0), Point(0, 0), context, name); static String _typeToJson(type) { return type.toString(); From 9ec03e0408ebff36606d89068449d4e2c5663998 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 16 Jun 2021 21:28:32 -0400 Subject: [PATCH 218/404] Fix path to SketchAssetConverter. The `/` that was removed was causing the path package to ignore `MainInfo().cwd.path`. --- lib/controllers/sketch_controller.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/controllers/sketch_controller.dart b/lib/controllers/sketch_controller.dart index c2f1c01d..7b2a8832 100644 --- a/lib/controllers/sketch_controller.dart +++ b/lib/controllers/sketch_controller.dart @@ -33,7 +33,7 @@ class SketchController extends Controller { AzureAssetService().projectUUID = designProject.id; - super.convert(designProject , apService ?? SketchAssetProcessor()); + super.convert(designProject, apService ?? SketchAssetProcessor()); } SketchProject generateSketchNodeTree( @@ -82,7 +82,7 @@ class SketchController extends Controller { process = await Process.start('npm', ['run', 'prod'], workingDirectory: - p.join(MainInfo().cwd.path, '/SketchAssetConverter')); + p.join(MainInfo().cwd.path, 'SketchAssetConverter')); await for (var event in process.stdout.transform(utf8.decoder)) { if (event.toLowerCase().contains('server is listening on port')) { From 5ee752e1bebbd9b5f5f77c01ee92b877d5aceca2 Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Thu, 17 Jun 2021 10:31:30 -0600 Subject: [PATCH 219/404] Updated PBDLConstraints to PBIntermediateConstraints, updated alignment generators, removed all uses of Align, created constraint generation service --- lib/controllers/interpret.dart | 4 + lib/eggs/injected_app_bar.dart | 14 +- .../attribute-helper/pb_size_helper.dart | 49 +++-- .../generators/layouts/pb_scaffold_gen.dart | 2 +- .../visual-widgets/pb_align_gen.dart | 39 ---- .../visual-widgets/pb_bitmap_gen.dart | 1 + .../visual-widgets/pb_container_gen.dart | 11 +- .../visual-widgets/pb_padding_gen.dart | 50 +++-- .../visual-widgets/pb_positioned_gen.dart | 3 +- lib/input/figma/entities/layers/ellipse.dart | 15 +- lib/input/figma/entities/layers/group.dart | 15 +- lib/input/figma/entities/layers/instance.dart | 15 +- lib/input/figma/entities/layers/line.dart | 6 +- .../figma/entities/layers/rectangle.dart | 11 +- .../entities/layers/regular_polygon.dart | 6 +- lib/input/figma/entities/layers/slice.dart | 6 +- lib/input/figma/entities/layers/star.dart | 6 +- lib/input/figma/entities/layers/text.dart | 12 +- lib/input/figma/entities/layers/vector.dart | 6 +- lib/input/sketch/entities/layers/bitmap.dart | 7 +- lib/input/sketch/entities/layers/oval.dart | 7 +- lib/input/sketch/entities/layers/polygon.dart | 7 +- .../sketch/entities/layers/rectangle.dart | 36 ++-- .../sketch/entities/layers/shape_group.dart | 7 +- .../sketch/entities/layers/shape_path.dart | 7 +- .../sketch/entities/layers/sketch_text.dart | 5 +- lib/input/sketch/entities/layers/star.dart | 6 +- .../entities/layers/symbol_instance.dart | 15 +- .../sketch/entities/layers/triangle.dart | 7 +- .../entities/alignments/injected_align.dart | 68 ------- .../entities/alignments/padding.dart | 41 ++-- .../entities/inherited_bitmap.dart | 4 +- .../entities/inherited_circle.dart | 23 ++- .../entities/inherited_container.dart | 36 ++-- .../entities/inherited_oval.dart | 6 +- .../entities/inherited_polygon.dart | 6 +- .../entities/inherited_scaffold.dart | 21 +- .../entities/inherited_shape_group.dart | 6 +- .../entities/inherited_shape_path.dart | 6 +- .../entities/inherited_star.dart | 6 +- .../entities/inherited_triangle.dart | 6 +- .../entities/injected_container.dart | 33 ++-- .../entities/layouts/column.dart | 23 +-- .../entities/layouts/row.dart | 13 +- .../entities/pb_shared_instance.dart | 39 ++-- .../pb_intermediate_constraints.dart | 38 ++++ .../subclasses/pb_intermediate_node.dart | 4 +- .../pb_visual_intermediate_node.dart | 6 +- .../helpers/pb_context.dart | 9 +- .../pb_alignment_generation_service.dart | 4 - .../pb_constraint_generation_service.dart | 183 ++++++++++++++++++ .../intermediate_auxillary_data.dart | 5 - 52 files changed, 591 insertions(+), 370 deletions(-) delete mode 100644 lib/generation/generators/visual-widgets/pb_align_gen.dart delete mode 100644 lib/interpret_and_optimize/entities/alignments/injected_align.dart create mode 100644 lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart create mode 100644 lib/interpret_and_optimize/services/pb_constraint_generation_service.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 37f6bd40..8192f6b3 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -11,6 +11,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_constraint_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; @@ -128,6 +129,9 @@ class Interpret { var stopwatch3 = Stopwatch()..start(); + intermediateTree = await PBConstraintGenerationService() + .implementConstraints(intermediateTree); + /// AlignGenerationService intermediateTree.rootNode = await alignGenerationService( intermediateTree.rootNode, currentContext, stopwatch3); diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 042c4885..e8ad9d2b 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -19,6 +19,10 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override String UUID; + @override + List get children => + [leadingItem, middleItem, trailingItem]; + PBIntermediateNode get leadingItem => getAttributeNamed('leading')?.attributeNode; PBIntermediateNode get middleItem => @@ -66,12 +70,10 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override void alignChild() { /// This align only modifies middleItem - var tempNode = InjectedContainer( - middleItem.bottomRightCorner, - middleItem.topLeftCorner, - middleItem.name, - middleItem.UUID, - )..addChild(middleItem); + var tempNode = InjectedContainer(middleItem.bottomRightCorner, + middleItem.topLeftCorner, middleItem.name, middleItem.UUID, + currentContext: currentContext) + ..addChild(middleItem); getAttributeNamed('title').attributeNode = tempNode; } diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index 0e49d53f..b3804039 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -15,8 +15,8 @@ class PBSizeHelper extends PBAttributesHelper { final buffer = StringBuffer(); var body = source.size ?? {}; - double height = body['height']; - double width = body['width']; + double relativeHeight = body['height']; + double relativeWidth = body['width']; //Add relative sizing if the widget has context var screenWidth; @@ -31,32 +31,39 @@ class PBSizeHelper extends PBAttributesHelper { .abs(); } - height = (height != null && screenHeight != null && screenHeight > 0.0) - ? height / screenHeight - : height; - width = (width != null && screenWidth != null && screenWidth > 0.0) - ? width / screenWidth - : width; + relativeHeight = + (relativeHeight != null && screenHeight != null && screenHeight > 0.0) + ? relativeHeight / screenHeight + : relativeHeight; + relativeWidth = + (relativeWidth != null && screenWidth != null && screenWidth > 0.0) + ? relativeWidth / screenWidth + : relativeWidth; + + if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { + var height = source.constraints.fixedHeight != null + ? body['height'].toStringAsFixed(3) + : 'MediaQuery.of(context).size.height * ${relativeHeight.toStringAsFixed(3)},'; + var width = source.constraints.fixedWidth != null + ? body['width'].toStringAsFixed(3) + : 'MediaQuery.of(context).size.width * ${relativeWidth.toStringAsFixed(3)},'; - if (generatorContext.sizingContext == SizingValueContext.MediaQueryValue) { - buffer.write( - 'width: MediaQuery.of(context).size.width * ${width.toStringAsFixed(3)},'); buffer.write( - 'height: MediaQuery.of(context).size.height * ${height.toStringAsFixed(3)},'); + 'constraints: BoxConstraints(maxHeight: ${height}, maxWidth: ${width}),'); } else if (generatorContext.sizingContext == SizingValueContext.LayoutBuilderValue) { - buffer - .write('width: constraints.maxWidth * ${width.toStringAsFixed(3)},'); buffer.write( - 'height: constraints.maxHeight * ${height.toStringAsFixed(3)},'); + 'width: constraints.maxWidth * ${relativeWidth.toStringAsFixed(3)},'); + buffer.write( + 'height: constraints.maxHeight * ${relativeHeight.toStringAsFixed(3)},'); } else { - height = body['height']; - width = body['width']; - if (width != null) { - buffer.write('width: ${width.toStringAsFixed(3)},'); + relativeHeight = body['height']; + relativeWidth = body['width']; + if (relativeWidth != null) { + buffer.write('width: ${relativeWidth.toStringAsFixed(3)},'); } - if (height != null) { - buffer.write('height: ${height.toStringAsFixed(3)},'); + if (relativeHeight != null) { + buffer.write('height: ${relativeHeight.toStringAsFixed(3)},'); } } diff --git a/lib/generation/generators/layouts/pb_scaffold_gen.dart b/lib/generation/generators/layouts/pb_scaffold_gen.dart index 004b969d..f703a699 100644 --- a/lib/generation/generators/layouts/pb_scaffold_gen.dart +++ b/lib/generation/generators/layouts/pb_scaffold_gen.dart @@ -10,7 +10,7 @@ class PBScaffoldGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext generatorContext) { - generatorContext.sizingContext = SizingValueContext.MediaQueryValue; + generatorContext.sizingContext = SizingValueContext.ScaleValue; var appBar = source.getAttributeNamed('appBar')?.attributeNode; var body = source.getAttributeNamed('body')?.attributeNode; var bottomNavBar = diff --git a/lib/generation/generators/visual-widgets/pb_align_gen.dart b/lib/generation/generators/visual-widgets/pb_align_gen.dart deleted file mode 100644 index 1ca3a22e..00000000 --- a/lib/generation/generators/visual-widgets/pb_align_gen.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/generation/generators/pb_generator.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:quick_log/quick_log.dart'; - -class PBAlignGenerator extends PBGenerator { - var log = Logger('Align Generator'); - PBAlignGenerator() : super(); - - @override - String generate(PBIntermediateNode source, PBContext generatorContext) { - if (source is InjectedAlign) { - var buffer = StringBuffer(); - buffer.write('Align('); - - source.alignX; - - buffer.write( - 'alignment: Alignment(${source.alignX.toStringAsFixed(2)}, ${source.alignY.toStringAsFixed(2)}),'); - - try { - source.child.currentContext = source.currentContext; - buffer.write( - 'child: ${source.child.generator.generate(source.child, generatorContext)},'); - } catch (e, stackTrace) { - MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); - log.error(e.toString()); - } - - buffer.write(')'); - return buffer.toString(); - } - } -} diff --git a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart index c65b0d0e..b868a998 100644 --- a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart @@ -27,3 +27,4 @@ class PBBitmapGenerator extends PBGenerator { return buffer.toString(); } } + diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index ba7391bc..5bbb7394 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -21,15 +21,14 @@ class PBContainerGenerator extends PBGenerator { if (source.auxiliaryData.borderInfo != null && source.auxiliaryData.borderInfo.isNotEmpty) { buffer.write(PBBoxDecorationHelper().generate(source, generatorContext)); - } - else { + } else { buffer.write(PBColorGenHelper().generate(source, generatorContext)); } - if (source.auxiliaryData.alignment != null) { - buffer.write( - 'alignment: Alignment(${(source.auxiliaryData.alignment['alignX'] as double).toStringAsFixed(2)}, ${(source.auxiliaryData.alignment['alignY'] as double).toStringAsFixed(2)}),'); - } + // if (source.auxiliaryData.alignment != null) { + // buffer.write( + // 'alignment: Alignment(${(source.auxiliaryData.alignment['alignX'] as double).toStringAsFixed(2)}, ${(source.auxiliaryData.alignment['alignY'] as double).toStringAsFixed(2)}),'); + // } if (source.child != null) { source.child.topLeftCorner = diff --git a/lib/generation/generators/visual-widgets/pb_padding_gen.dart b/lib/generation/generators/visual-widgets/pb_padding_gen.dart index 5b4f7c5e..1c7d7bb7 100644 --- a/lib/generation/generators/visual-widgets/pb_padding_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_padding_gen.dart @@ -4,21 +4,26 @@ import 'package:parabeac_core/generation/generators/value_objects/template_strat import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:tuple/tuple.dart'; import '../pb_generator.dart'; class PBPaddingGen extends PBGenerator { PBPaddingGen() : super(); String relativePadding( - TemplateStrategy strategy, bool isVertical, double value) { + TemplateStrategy strategy, double value, Tuple2 paddingPosition) { var fixedValue = value.toStringAsFixed(2); if (strategy is StatelessTemplateStrategy) { return 'constraints.max' + - (isVertical ? 'Height' : 'Width') + + (paddingPosition.item1 == 'top' || paddingPosition.item1 == 'bottom' + ? 'Height' + : 'Width') + ' * $fixedValue'; } return 'MediaQuery.of(context).size.' + - (isVertical ? 'height' : 'width') + + (paddingPosition.item1 == 'top' || paddingPosition.item1 == 'bottom' + ? 'height' + : 'width') + ' * $fixedValue'; } @@ -36,26 +41,31 @@ class PBPaddingGen extends PBGenerator { buffer.write('Padding('); buffer.write('padding: EdgeInsets.only('); - final paddingPositionsW = ['left', 'right']; - final paddingPositionsH = ['bottom', 'top']; + final paddingPositions = [ + Tuple2( + 'left', + padding.childToParentConstraints.pinLeft, + ), + Tuple2( + 'right', + padding.childToParentConstraints.pinRight, + ), + Tuple2( + 'bottom', + padding.childToParentConstraints.pinBottom, + ), + Tuple2( + 'top', + padding.childToParentConstraints.pinTop, + ) + ]; + var reflectedPadding = reflect(padding); - for (var position in paddingPositionsW) { - var value = reflectedPadding.getField(Symbol(position)).reflectee; - var isVertical = false; - if (position == 'top' || position == 'bottom') { - isVertical = true; - } - if (value != null) { - buffer.write( - '$position: ${relativePadding(source.generator.templateStrategy, isVertical, value)},'); - } - } - for (var position in paddingPositionsH) { - var value = reflectedPadding.getField(Symbol(position)).reflectee; - if (value != null) { + for (var position in paddingPositions) { + if (reflectedPadding.getField(Symbol(position.item1)).reflectee != 0) { buffer.write( - '$position: ${relativePadding(source.generator.templateStrategy, true, value)},'); + '$position: ${relativePadding(source.generator.templateStrategy, reflectedPadding.getField(Symbol(position.item1)).reflectee, position)},'); } } diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 780b8df8..8c5e0ecf 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -25,8 +25,7 @@ class PBPositionedGenerator extends PBGenerator { right: source.valueHolder.right, ); - if (generatorContext.sizingContext == - SizingValueContext.MediaQueryValue) { + if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { multStringH = 'MediaQuery.of(context).size.width * '; multStringV = 'MediaQuery.of(context).size.height *'; _calculateRelativeValues(source, valueHolder); diff --git a/lib/input/figma/entities/layers/ellipse.dart b/lib/input/figma/entities/layers/ellipse.dart index 03555e73..ed4b6223 100644 --- a/lib/input/figma/entities/layers/ellipse.dart +++ b/lib/input/figma/entities/layers/ellipse.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -82,12 +83,14 @@ class FigmaEllipse extends FigmaVector @override Future interpretNode(PBContext currentContext) async { imageReference = FigmaAssetProcessor().processImage(UUID); - return Future.value(InheritedBitmap( - this, - name, - currentContext: currentContext, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), - )); + return Future.value( + InheritedBitmap(this, name, + currentContext: currentContext, + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width)), + ); } @override diff --git a/lib/input/figma/entities/layers/group.dart b/lib/input/figma/entities/layers/group.dart index 5c3bd260..b16cd6ec 100644 --- a/lib/input/figma/entities/layers/group.dart +++ b/lib/input/figma/entities/layers/group.dart @@ -13,6 +13,7 @@ import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -114,12 +115,14 @@ class Group extends FigmaFrame implements AbstractFigmaNodeFactory, Image { children.clear(); - return Future.value(InheritedBitmap( - this, - name, - currentContext: currentContext, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), - )); + return Future.value( + InheritedBitmap(this, name, + currentContext: currentContext, + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width)), + ); } return Future.value(TempGroupLayoutNode( this, diff --git a/lib/input/figma/entities/layers/instance.dart b/lib/input/figma/entities/layers/instance.dart index a2ae14aa..41795859 100644 --- a/lib/input/figma/entities/layers/instance.dart +++ b/lib/input/figma/entities/layers/instance.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/objects/override_value.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -95,13 +96,13 @@ class Instance extends FigmaFrame @override Future interpretNode(PBContext currentContext) { /// TODO: Check if `sharedParamValues` exits and pass to it, default to emptu for now - var sym = PBSharedInstanceIntermediateNode( - this, - componentId, - sharedParamValues: [], - currentContext: currentContext, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), - ); + var sym = PBSharedInstanceIntermediateNode(this, componentId, + sharedParamValues: [], + currentContext: currentContext, + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width)); return Future.value(sym); } diff --git a/lib/input/figma/entities/layers/line.dart b/lib/input/figma/entities/layers/line.dart index 3804ef74..05e6b280 100644 --- a/lib/input/figma/entities/layers/line.dart +++ b/lib/input/figma/entities/layers/line.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart' import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -77,7 +78,10 @@ class FigmaLine extends FigmaVector implements AbstractFigmaNodeFactory { boundaryRectangle.y + boundaryRectangle.height, ), name, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width), )); } diff --git a/lib/input/figma/entities/layers/rectangle.dart b/lib/input/figma/entities/layers/rectangle.dart index 0efaa3c2..c74999e6 100644 --- a/lib/input/figma/entities/layers/rectangle.dart +++ b/lib/input/figma/entities/layers/rectangle.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -103,7 +104,10 @@ class FigmaRectangle extends FigmaVector this, name, currentContext: currentContext, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width), )); } PBBorder border; @@ -129,7 +133,10 @@ class FigmaRectangle extends FigmaVector ? toHex(style.borders[0].color) : null }, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width), )); } diff --git a/lib/input/figma/entities/layers/regular_polygon.dart b/lib/input/figma/entities/layers/regular_polygon.dart index 8f7616c5..45de8465 100644 --- a/lib/input/figma/entities/layers/regular_polygon.dart +++ b/lib/input/figma/entities/layers/regular_polygon.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -76,7 +77,10 @@ class FigmaRegularPolygon extends FigmaVector this, name, currentContext: currentContext, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width), )); } diff --git a/lib/input/figma/entities/layers/slice.dart b/lib/input/figma/entities/layers/slice.dart index 136b0dde..03c11a64 100644 --- a/lib/input/figma/entities/layers/slice.dart +++ b/lib/input/figma/entities/layers/slice.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart' import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -75,7 +76,10 @@ class FigmaSlice extends FigmaNode implements FigmaNodeFactory { boundaryRectangle.y + boundaryRectangle.height), name, currentContext: currentContext, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width), )); } diff --git a/lib/input/figma/entities/layers/star.dart b/lib/input/figma/entities/layers/star.dart index 4a6453a9..56f8504c 100644 --- a/lib/input/figma/entities/layers/star.dart +++ b/lib/input/figma/entities/layers/star.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -75,7 +76,10 @@ class FigmaStar extends FigmaVector implements AbstractFigmaNodeFactory { name, currentContext: currentContext, referenceImage: imageReference, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width), )); } diff --git a/lib/input/figma/entities/layers/text.dart b/lib/input/figma/entities/layers/text.dart index 652ae26e..59361ceb 100644 --- a/lib/input/figma/entities/layers/text.dart +++ b/lib/input/figma/entities/layers/text.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -100,9 +101,16 @@ class FigmaText extends FigmaVector implements AbstractFigmaNodeFactory, Text { name, currentContext: currentContext, isBackgroundVisible: style.backgroundColor != null, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width), )..addChild( - InheritedText(this, name, currentContext: currentContext), + InheritedText( + this, + name, + currentContext: currentContext, + ), )); } diff --git a/lib/input/figma/entities/layers/vector.dart b/lib/input/figma/entities/layers/vector.dart index b4034965..3b15adca 100644 --- a/lib/input/figma/entities/layers/vector.dart +++ b/lib/input/figma/entities/layers/vector.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -98,7 +99,10 @@ class FigmaVector extends FigmaNode implements FigmaNodeFactory, Image { this, name, currentContext: currentContext, - constraints: convertFigmaConstraintToPBDLConstraint(constraints), + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width), )); } diff --git a/lib/input/sketch/entities/layers/bitmap.dart b/lib/input/sketch/entities/layers/bitmap.dart index 0863b530..4542b319 100644 --- a/lib/input/sketch/entities/layers/bitmap.dart +++ b/lib/input/sketch/entities/layers/bitmap.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_deny_list_helper.dart'; @@ -113,8 +114,10 @@ class Bitmap extends SketchNode implements SketchNodeFactory, Image { } return Future.value(InheritedBitmap(this, name, currentContext: currentContext, - constraints: - convertSketchConstraintToPBDLConstraint(resizingConstraint))); + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width))); } @JsonKey(name: 'image') diff --git a/lib/input/sketch/entities/layers/oval.dart b/lib/input/sketch/entities/layers/oval.dart index 7010d028..1b065851 100644 --- a/lib/input/sketch/entities/layers/oval.dart +++ b/lib/input/sketch/entities/layers/oval.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_oval.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -123,8 +124,10 @@ class Oval extends AbstractShapeLayer implements SketchNodeFactory { return Future.value(InheritedOval(this, name, currentContext: currentContext, image: image, - constraints: - convertSketchConstraintToPBDLConstraint(resizingConstraint))); + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width))); } @override diff --git a/lib/input/sketch/entities/layers/polygon.dart b/lib/input/sketch/entities/layers/polygon.dart index 0d407f68..4005757d 100644 --- a/lib/input/sketch/entities/layers/polygon.dart +++ b/lib/input/sketch/entities/layers/polygon.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_polygon.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -125,8 +126,10 @@ class Polygon extends AbstractShapeLayer implements SketchNodeFactory { return Future.value(InheritedPolygon(this, name, currentContext: currentContext, image: image, - constraints: - convertSketchConstraintToPBDLConstraint(resizingConstraint))); + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width))); } @override diff --git a/lib/input/sketch/entities/layers/rectangle.dart b/lib/input/sketch/entities/layers/rectangle.dart index b0cacfb1..ac991c9d 100644 --- a/lib/input/sketch/entities/layers/rectangle.dart +++ b/lib/input/sketch/entities/layers/rectangle.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/input/sketch/entities/style/border.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -132,21 +133,26 @@ class Rectangle extends AbstractShapeLayer border = b; } } - return Future.value(InheritedContainer( - this, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - name, - currentContext: currentContext, - borderInfo: { - 'borderRadius': - style.borderOptions.isEnabled ? points[0]['cornerRadius'] : null, - 'borderColorHex': border != null ? toHex(border.color) : null, - 'borderThickness': border != null ? border.thickness : null - }, - constraints: convertSketchConstraintToPBDLConstraint(resizingConstraint), - )); + return Future.value( + InheritedContainer( + this, + Point(boundaryRectangle.x, boundaryRectangle.y), + Point(boundaryRectangle.x + boundaryRectangle.width, + boundaryRectangle.y + boundaryRectangle.height), + name, + currentContext: currentContext, + borderInfo: { + 'borderRadius': style.borderOptions.isEnabled + ? points[0]['cornerRadius'] + : null, + 'borderColorHex': border != null ? toHex(border.color) : null, + 'borderThickness': border != null ? border.thickness : null + }, + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width)), + ); } @override diff --git a/lib/input/sketch/entities/layers/shape_group.dart b/lib/input/sketch/entities/layers/shape_group.dart index 82b4d2d8..1a95e670 100644 --- a/lib/input/sketch/entities/layers/shape_group.dart +++ b/lib/input/sketch/entities/layers/shape_group.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -127,8 +128,10 @@ class ShapeGroup extends AbstractGroupLayer implements SketchNodeFactory { return InheritedShapeGroup(this, name, currentContext: currentContext, image: image, - constraints: - convertSketchConstraintToPBDLConstraint(resizingConstraint)); + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width)); } @override diff --git a/lib/input/sketch/entities/layers/shape_path.dart b/lib/input/sketch/entities/layers/shape_path.dart index a06b7388..19358fd8 100644 --- a/lib/input/sketch/entities/layers/shape_path.dart +++ b/lib/input/sketch/entities/layers/shape_path.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -122,8 +123,10 @@ class ShapePath extends AbstractShapeLayer implements SketchNodeFactory { return Future.value(InheritedShapePath(this, name, currentContext: currentContext, image: image, - constraints: - convertSketchConstraintToPBDLConstraint(resizingConstraint))); + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width))); } @override diff --git a/lib/input/sketch/entities/layers/sketch_text.dart b/lib/input/sketch/entities/layers/sketch_text.dart index 4dae1edc..e0e1430b 100644 --- a/lib/input/sketch/entities/layers/sketch_text.dart +++ b/lib/input/sketch/entities/layers/sketch_text.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -137,8 +138,10 @@ class SketchText extends SketchNode implements SketchNodeFactory, Text { name, Uuid().v4(), currentContext: currentContext, - constraints: + constraints: PBIntermediateConstraints.fromConstraints( convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width), )..addChild( InheritedText(this, name, currentContext: currentContext), )); diff --git a/lib/input/sketch/entities/layers/star.dart b/lib/input/sketch/entities/layers/star.dart index 878abd25..0626191c 100644 --- a/lib/input/sketch/entities/layers/star.dart +++ b/lib/input/sketch/entities/layers/star.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_star.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -125,7 +126,10 @@ class Star extends AbstractShapeLayer implements SketchNodeFactory { name, currentContext: currentContext, image: image, - constraints: convertSketchConstraintToPBDLConstraint(resizingConstraint), + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width), )); } diff --git a/lib/input/sketch/entities/layers/symbol_instance.dart b/lib/input/sketch/entities/layers/symbol_instance.dart index 97a9a627..60132147 100644 --- a/lib/input/sketch/entities/layers/symbol_instance.dart +++ b/lib/input/sketch/entities/layers/symbol_instance.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -146,13 +147,13 @@ class SymbolInstance extends SketchNode @override Future interpretNode(PBContext currentContext) { - var sym = PBSharedInstanceIntermediateNode( - this, - symbolID, - sharedParamValues: _extractParameters(), - currentContext: currentContext, - constraints: convertSketchConstraintToPBDLConstraint(resizingConstraint), - ); + var sym = PBSharedInstanceIntermediateNode(this, symbolID, + sharedParamValues: _extractParameters(), + currentContext: currentContext, + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width)); return Future.value(sym); } diff --git a/lib/input/sketch/entities/layers/triangle.dart b/lib/input/sketch/entities/layers/triangle.dart index d6db623c..f1cfaf1b 100644 --- a/lib/input/sketch/entities/layers/triangle.dart +++ b/lib/input/sketch/entities/layers/triangle.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_triangle.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -124,8 +125,10 @@ class Triangle extends AbstractShapeLayer implements SketchNodeFactory { return Future.value(InheritedTriangle(this, name, currentContext: currentContext, image: image, - constraints: - convertSketchConstraintToPBDLConstraint(resizingConstraint))); + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width))); } @override diff --git a/lib/interpret_and_optimize/entities/alignments/injected_align.dart b/lib/interpret_and_optimize/entities/alignments/injected_align.dart deleted file mode 100644 index b6ad9f27..00000000 --- a/lib/interpret_and_optimize/entities/alignments/injected_align.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:parabeac_core/generation/generators/visual-widgets/pb_align_gen.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; - -class InjectedAlign extends PBVisualIntermediateNode - implements PBInjectedIntermediate { - double alignX; - double alignY; - - InjectedAlign(Point topLeftCorner, Point bottomRightCorner, - PBContext currentContext, String name) - : super(topLeftCorner, bottomRightCorner, currentContext, name) { - generator = PBAlignGenerator(); - } - - @override - void addChild(PBIntermediateNode node) { - if (child is TempGroupLayoutNode) { - child.addChild(node); - return; - } - // If there's multiple children add a temp group so that layout service lays the children out. - if (child != null) { - var temp = TempGroupLayoutNode(null, currentContext, name); - temp.addChild(child); - temp.addChild(node); - child = temp; - } - child = node; - } - - @override - void alignChild() { - var maxX = (topLeftCorner.x - bottomRightCorner.x).abs() - - (child.bottomRightCorner.x - child.topLeftCorner.x).abs(); - var parentCenterX = (topLeftCorner.x + bottomRightCorner.x) / 2; - var childCenterX = (child.topLeftCorner.x + child.bottomRightCorner.x) / 2; - var alignmentX = 0.0; - - if (maxX != 0.0) { - alignmentX = ((childCenterX - parentCenterX) / maxX) * 2; - } - - var parentCenterY = (topLeftCorner.y + bottomRightCorner.y) / 2; - var maxY = (topLeftCorner.y - bottomRightCorner.y).abs() - - (child.bottomRightCorner.y - child.topLeftCorner.y).abs(); - var childCenterY = (child.topLeftCorner.y + child.bottomRightCorner.y) / 2; - var alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; - - if (maxY != 0.0) { - alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; - } - - if (alignmentX.isNaN) { - alignmentX = 0; - } - if (alignmentY.isNaN) { - alignmentY = 0; - } - - alignX = alignmentX.toDouble(); - alignY = alignmentY.toDouble(); - } -} diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index fa67b3d3..6e748734 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -1,11 +1,11 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_padding_gen.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class Padding extends PBVisualIntermediateNode { - double left, right, top, bottom, screenWidth, screenHeight; @override @@ -21,16 +21,19 @@ class Padding extends PBVisualIntermediateNode { @override Point bottomRightCorner; - Padding(this.UUID, - {this.left, - this.right, - this.top, - this.bottom, - this.topLeftCorner, - this.bottomRightCorner, - this.currentContext}) - : super(topLeftCorner, bottomRightCorner, currentContext, '', - UUID: UUID) { + PBIntermediateConstraints childToParentConstraints; + + Padding( + this.UUID, + this.childToParentConstraints, { + this.left = 0, + this.right = 0, + this.top = 0, + this.bottom = 0, + this.topLeftCorner, + this.bottomRightCorner, + this.currentContext, + }) : super(topLeftCorner, bottomRightCorner, currentContext, '', UUID: UUID) { generator = PBPaddingGen(); } @@ -57,21 +60,21 @@ class Padding extends PBVisualIntermediateNode { /// executes just before the generator generates the code for the [PBIntermediateNode]. screenHeight = screenHeight == 0 ? 1 : screenHeight; screenWidth = screenWidth == 0 ? 1 : screenWidth; - if (left != null) { + if (left != null && !childToParentConstraints.pinLeft) { left = (left / screenWidth); - left = left < 0.01 ? null : left; + left = left < 0.01 ? 0.0 : left; } - if (right != null) { + if (right != null && !childToParentConstraints.pinRight) { right = right / screenWidth; - right = right < 0.01 ? null : right; + right = right < 0.01 ? 0.0 : right; } - if (top != null) { + if (top != null && !childToParentConstraints.pinTop) { top = top / screenHeight; - top = top < 0.01 ? null : top; + top = top < 0.01 ? 0.0 : top; } - if (bottom != null) { + if (bottom != null && !childToParentConstraints.pinBottom) { bottom = bottom / screenHeight; - bottom = bottom < 0.01 ? null : bottom; + bottom = bottom < 0.01 ? 0.0 : bottom; } } diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index 60f8f78c..f27c6c70 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -4,9 +4,9 @@ import 'package:parabeac_core/design_logic/image.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -27,7 +27,7 @@ class InheritedBitmap extends PBVisualIntermediateNode InheritedBitmap(this.originalRef, String name, {PBContext currentContext, this.referenceImage, - PBDLConstraints constraints}) + PBIntermediateConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index da19fb5f..ca50c8ae 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -1,7 +1,7 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -34,9 +34,6 @@ class InheritedCircle extends PBVisualIntermediateNode auxiliaryData.borderInfo = {}; auxiliaryData.borderInfo['shape'] = 'circle'; - auxiliaryData.alignment = alignX != null && alignY != null - ? {'alignX': alignX, 'alignY': alignY} - : null; } @override @@ -55,15 +52,17 @@ class InheritedCircle extends PBVisualIntermediateNode child = node; } - /// Should add positional info ONLY to parent node. This should only be sent here if the parent and child node is only one-to-one. - /// - /// alignCenterX/y = ((childCenter - parentCenter) / max) if > 0.5 subtract 0.5 if less than 0.5 multiply times -1 @override void alignChild() { - var align = - InjectedAlign(topLeftCorner, bottomRightCorner, currentContext, ''); - align.addChild(child); - align.alignChild(); - child = align; + var padding = Padding('', child.constraints, + left: child.topLeftCorner.x - topLeftCorner.x, + right: bottomRightCorner.x - child.bottomRightCorner.x, + top: child.topLeftCorner.y - topLeftCorner.y, + bottom: child.bottomRightCorner.y - bottomRightCorner.y, + topLeftCorner: topLeftCorner, + bottomRightCorner: bottomRightCorner, + currentContext: currentContext); + padding.addChild(child); + child = padding; } } diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 1b637eab..7d94408c 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -2,12 +2,13 @@ import 'package:parabeac_core/design_logic/color.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -29,7 +30,7 @@ class InheritedContainer extends PBVisualIntermediateNode PBContext currentContext, Map borderInfo, this.isBackgroundVisible = true, - PBDLConstraints constraints}) + PBIntermediateConstraints constraints}) : super(topLeftCorner, bottomRightCorner, currentContext, name, UUID: originalRef.UUID ?? '', constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { @@ -57,10 +58,6 @@ class InheritedContainer extends PBVisualIntermediateNode } } - auxiliaryData.alignment = alignX != null && alignY != null - ? {'alignX': alignX, 'alignY': alignY} - : null; - auxiliaryData.borderInfo = borderInfo; assert(originalRef != null, @@ -83,17 +80,26 @@ class InheritedContainer extends PBVisualIntermediateNode child = node; } - /// Should add positional info ONLY to parent node. This should only be sent here if the parent and child node is only one-to-one. - /// - /// alignCenterX/y = ((childCenter - parentCenter) / max) if > 0.5 subtract 0.5 if less than 0.5 multiply times -1 @override void alignChild() { if (child != null) { - var align = - InjectedAlign(topLeftCorner, bottomRightCorner, currentContext, ''); - align.addChild(child); - align.alignChild(); - child = align; + /// Refactor to child.constraints != null + if (child is! InheritedText) { + var left = child.topLeftCorner.x - topLeftCorner.x ?? 0.0; + var right = bottomRightCorner.x - child.bottomRightCorner.x ?? 0.0; + var top = child.topLeftCorner.y - topLeftCorner.y ?? 0.0; + var bottom = child.bottomRightCorner.y - bottomRightCorner.y ?? 0.0; + var padding = Padding('', child.constraints, + left: left, + right: right, + top: top, + bottom: bottom, + topLeftCorner: topLeftCorner, + bottomRightCorner: bottomRightCorner, + currentContext: currentContext); + padding.addChild(child); + child = padding; + } } } } diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index 93f11a24..fe4d2a6a 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -5,9 +5,9 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -23,7 +23,9 @@ class InheritedOval extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedOval(this.originalRef, String name, - {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) + {Uint8List image, + PBContext currentContext, + PBIntermediateConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index 248a671d..30e18e41 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -5,9 +5,9 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -21,7 +21,9 @@ class InheritedPolygon extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedPolygon(this.originalRef, String name, - {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) + {Uint8List image, + PBContext currentContext, + PBIntermediateConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 1170fec1..f5cff0d1 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/eggs/injected_app_bar.dart'; import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; @@ -30,6 +30,9 @@ class InheritedScaffold extends PBVisualIntermediateNode @override PBIntermediateNode get child => getAttributeNamed('body')?.attributeNode; + @override + List get children => [child, navbar, tabbar]; + PBIntermediateNode get navbar => getAttributeNamed('appBar')?.attributeNode; PBIntermediateNode get tabbar => @@ -76,7 +79,6 @@ class InheritedScaffold extends PBVisualIntermediateNode addAttribute(PBAttribute('body')); } - @override List layoutInstruction(List layer) { return layer; } @@ -122,11 +124,16 @@ class InheritedScaffold extends PBVisualIntermediateNode @override void alignChild() { if (child != null) { - var align = - InjectedAlign(topLeftCorner, bottomRightCorner, currentContext, ''); - align.addChild(child); - align.alignChild(); - child = align; + var padding = Padding('', child.constraints, + left: child.topLeftCorner.x - topLeftCorner.x, + right: bottomRightCorner.x - child.bottomRightCorner.x, + top: child.topLeftCorner.y - topLeftCorner.y, + bottom: child.bottomRightCorner.y - bottomRightCorner.y, + topLeftCorner: topLeftCorner, + bottomRightCorner: bottomRightCorner, + currentContext: currentContext); + padding.addChild(child); + child = padding; } } } diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index f984e046..83877f53 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -5,9 +5,9 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -21,7 +21,9 @@ class InheritedShapeGroup extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedShapeGroup(this.originalRef, String name, - {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) + {Uint8List image, + PBContext currentContext, + PBIntermediateConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 53a0e294..19517ffe 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -8,9 +8,9 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/input/sketch/entities/layers/shape_path.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -24,7 +24,9 @@ class InheritedShapePath extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedShapePath(this.originalRef, String name, - {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) + {Uint8List image, + PBContext currentContext, + PBIntermediateConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index 8f532658..59edb482 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -5,9 +5,9 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -21,7 +21,9 @@ class InheritedStar extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedStar(this.originalRef, String name, - {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) + {Uint8List image, + PBContext currentContext, + PBIntermediateConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 06c35a1b..08def46f 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -5,9 +5,9 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -21,7 +21,9 @@ class InheritedTriangle extends PBVisualIntermediateNode PrototypeNode prototypeNode; InheritedTriangle(this.originalRef, String name, - {Uint8List image, PBContext currentContext, PBDLConstraints constraints}) + {Uint8List image, + PBContext currentContext, + PBIntermediateConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 9aeea4a1..79c8dcc5 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -1,12 +1,14 @@ +import 'dart:ffi'; + import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -20,11 +22,9 @@ class InjectedContainer extends PBVisualIntermediateNode Point topLeftCorner, String name, String UUID, { - double alignX, - double alignY, String color, PBContext currentContext, - PBDLConstraints constraints, + PBIntermediateConstraints constraints, }) : super(topLeftCorner, bottomRightCorner, currentContext, name, UUID: UUID, constraints: constraints) { generator = PBContainerGenerator(); @@ -33,10 +33,6 @@ class InjectedContainer extends PBVisualIntermediateNode 'width': (bottomRightCorner.x - topLeftCorner.x).abs(), 'height': (bottomRightCorner.y - topLeftCorner.y).abs(), }; - - auxiliaryData.alignment = alignX != null && alignY != null - ? {'alignX': alignX, 'alignY': alignY} - : null; } @override @@ -55,15 +51,18 @@ class InjectedContainer extends PBVisualIntermediateNode child = node; } - /// Should add positional info ONLY to parent node. This should only be sent here if the parent and child node is only one-to-one. - /// - /// alignCenterX/y = ((childCenter - parentCenter) / max) if > 0.5 subtract 0.5 if less than 0.5 multiply times -1 @override void alignChild() { - var align = - InjectedAlign(topLeftCorner, bottomRightCorner, currentContext, ''); - align.addChild(child); - align.alignChild(); - child = align; + /// Add Padding that takes into account pinning (hard values). + var padding = Padding('', child.constraints, + left: child.topLeftCorner.x - topLeftCorner.x, + right: bottomRightCorner.x - child.bottomRightCorner.x, + top: child.topLeftCorner.y - topLeftCorner.y, + bottom: child.bottomRightCorner.y - bottomRightCorner.y, + topLeftCorner: topLeftCorner, + bottomRightCorner: bottomRightCorner, + currentContext: currentContext); + padding.child = child; + child = padding; } } diff --git a/lib/interpret_and_optimize/entities/layouts/column.dart b/lib/interpret_and_optimize/entities/layouts/column.dart index 8628ae04..5fc2bf29 100644 --- a/lib/interpret_and_optimize/entities/layouts/column.dart +++ b/lib/interpret_and_optimize/entities/layouts/column.dart @@ -9,7 +9,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/handle_flex.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:uuid/uuid.dart'; ///Colum contains nodes that are all `vertical` to each other, without overlapping eachother @@ -40,12 +39,6 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { generator = PBColumnGenerator(); } - // checkCrossAxisAlignment() { - // // TODO: this is the default for now - // alignment['crossAxisAlignment'] = - // 'crossAxisAlignment: CrossAxisAlignment.start'; - // } - @override void alignChildren() { checkCrossAxisAlignment(); @@ -69,18 +62,12 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { var columnMinX = topLeftCorner.x; var columnMaxX = bottomRightCorner.x; - if (topLeftCorner.x < currentContext.screenTopLeftCorner.x) { - columnMinX = currentContext.screenTopLeftCorner.x; - } - if (bottomRightCorner.x > currentContext.screenBottomRightCorner.x) { - columnMaxX = currentContext.screenBottomRightCorner.x; - } - for (var i = 0; i < children.length; i++) { - //TODO: Check to see if the left or right padding or both is equal to 0 or even negative if that's even possible. - var padding = Padding(Uuid().v4(), - left: children[i].topLeftCorner.x - columnMinX, - right: columnMaxX - children[i].bottomRightCorner.x, + var padding = Padding('', children[i].constraints, + left: children[i].topLeftCorner.x - columnMinX ?? 0.0, + right: columnMaxX - children[i].bottomRightCorner.x ?? 0.0, + top: 0.0, + bottom: 0.0, topLeftCorner: children[i].topLeftCorner, bottomRightCorner: children[i].bottomRightCorner, currentContext: currentContext); diff --git a/lib/interpret_and_optimize/entities/layouts/row.dart b/lib/interpret_and_optimize/entities/layouts/row.dart index 9c0d2684..71bab952 100644 --- a/lib/interpret_and_optimize/entities/layouts/row.dart +++ b/lib/interpret_and_optimize/entities/layouts/row.dart @@ -9,7 +9,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:uuid/uuid.dart'; ///Row contains nodes that are all `horizontal` to each other, without overlapping eachother @@ -25,9 +24,6 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { @override final String UUID; - // @override - // PBContext currentContext; - @override PrototypeNode prototypeNode; @@ -69,10 +65,11 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { } for (var i = 0; i < children.length; i++) { - //TODO: Check to see if the left or right padding or both is equal to 0 or even negative if that's even possible. - var padding = Padding(Uuid().v4(), - top: children[i].topLeftCorner.y - rowMinY, - bottom: rowMaxY - children[i].bottomRightCorner.y, + var padding = Padding('', children[i].constraints, + top: children[i].topLeftCorner.y - rowMinY ?? 0.0, + bottom: rowMaxY - children[i].bottomRightCorner.y ?? 0.0, + left: 0.0, + right: 0.0, topLeftCorner: children[i].topLeftCorner, bottomRightCorner: children[i].bottomRightCorner, currentContext: currentContext); diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index d90cb552..9461fc09 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -2,17 +2,16 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_instancesym_gen.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'alignments/injected_align.dart'; - /// As some nodes are shared throughout the project, shared instances are pointers to shared master nodes with overridable properties. /// Superclass: PBSharedIntermediateNode @@ -47,7 +46,7 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode Point topLeftCorner, Point bottomRightCorner, PBContext currentContext, - PBDLConstraints constraints}) + PBIntermediateConstraints constraints}) : super( Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y), @@ -65,13 +64,13 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode } generator = PBSymbolInstanceGenerator(); - overrideValues = sharedParamValues - .map((v) { - var symOvrValue = PBSymbolInstanceOverridableValue(v.UUID, v.value, v.type); - overrideValuesMap[v.overrideName] = symOvrValue; - return symOvrValue; }) - .toList() - ..removeWhere((v) => v == null || v.value == null); + overrideValues = sharedParamValues.map((v) { + var symOvrValue = + PBSymbolInstanceOverridableValue(v.UUID, v.value, v.type); + overrideValuesMap[v.overrideName] = symOvrValue; + return symOvrValue; + }).toList() + ..removeWhere((v) => v == null || v.value == null); } @override @@ -80,11 +79,16 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @override void alignChild() { if (child != null) { - var align = - InjectedAlign(topLeftCorner, bottomRightCorner, currentContext, ''); - align.addChild(child); - align.alignChild(); - child = align; + var padding = Padding('', child.constraints, + left: child.topLeftCorner.x - topLeftCorner.x, + right: bottomRightCorner.x - child.bottomRightCorner.x, + top: child.topLeftCorner.y - topLeftCorner.y, + bottom: child.bottomRightCorner.y - bottomRightCorner.y, + topLeftCorner: topLeftCorner, + bottomRightCorner: bottomRightCorner, + currentContext: currentContext); + padding.addChild(child); + child = padding; } } } @@ -103,7 +107,8 @@ class PBSharedParameterValue { final String _overrideName; String get overrideName => _overrideName; - String get name => SN_UUIDtoVarName[PBInputFormatter.findLastOf(_overrideName, '/')]; + String get name => + SN_UUIDtoVarName[PBInputFormatter.findLastOf(_overrideName, '/')]; PBSharedParameterValue( this._type, diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart new file mode 100644 index 00000000..11b78f8e --- /dev/null +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart @@ -0,0 +1,38 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; + +/// Named PBDL in anticipation of the refactor where PBDL becomes the design standard. +/// Each property must be set. +/// TODO: Use https://pub.dev/packages/meta to make these named parameters required. +class PBIntermediateConstraints { + PBIntermediateConstraints( + {this.pinLeft, + this.pinRight, + this.pinTop, + this.pinBottom, + this.fixedHeight, + this.fixedWidth}); + + PBIntermediateConstraints.fromConstraints( + PBDLConstraints constraints, double height, double width) { + pinLeft = constraints.pinLeft; + pinRight = constraints.pinRight; + pinTop = constraints.pinTop; + pinBottom = constraints.pinBottom; + if (constraints.fixedHeight) { + fixedHeight = height; + } + if (constraints.fixedWidth) { + fixedWidth = width; + } + } + bool pinLeft; + bool pinRight; + bool pinTop; + bool pinBottom; + + /// If value is null, then the height is not fixed. + double fixedHeight; + + /// If value is null, then the width is not fixed. + double fixedWidth; +} diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 88674416..75f34243 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -3,7 +3,7 @@ import 'dart:math'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; @@ -23,7 +23,7 @@ abstract class PBIntermediateNode extends TraversableNode { final String UUID; - PBDLConstraints constraints; + PBIntermediateConstraints constraints; /// Map representing the attributes of [this]. /// The key represents the name of the attribute, while the value diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart index 2a4d0f1b..9ff85182 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart @@ -1,16 +1,14 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; /// Represents a typical node that the end-user could see, it usually has properties such as size and color. It only contains a single child, unlike PBLayoutIntermediateNode that contains a set of children. /// Superclass: PBIntermediateNode abstract class PBVisualIntermediateNode extends PBIntermediateNode { - // final String UUID; - PBVisualIntermediateNode(Point topLeftCorner, Point bottomRightCorner, PBContext currentContext, String name, - {String UUID, PBDLConstraints constraints}) + {String UUID, PBIntermediateConstraints constraints}) : super(topLeftCorner, bottomRightCorner, UUID, name, currentContext: currentContext, constraints: constraints); diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index e289e15c..2e35597f 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -29,8 +29,15 @@ class PBContext { } enum SizingValueContext { + /// Should be hardcoded values PointValue, - MediaQueryValue, + + /// Should be using BoxConstraints to scale + ScaleValue, + + /// Should conform to the Layout Builder code, usually used when calling views. LayoutBuilderValue, + + /// TODO: Remove AppBarChild, } diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index 65f0e7a0..9c740c0c 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -1,5 +1,3 @@ -import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; @@ -8,8 +6,6 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:quick_log/quick_log.dart'; -import '../entities/alignments/injected_positioned.dart'; - /// PBAlignmentGenerationService: /// Interpret the alignment relationship between a child node and a parent Visual or Layout Node. After interpretation, inject the proper alignment whether that’s Padding based or Flex-based. /// Input: PBIntermediateNode Tree diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart new file mode 100644 index 00000000..ee879e7f --- /dev/null +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -0,0 +1,183 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; + +///tree.where((element) => element != null).toList().reversed.map((e) => e.name).toList() +class PBConstraintGenerationService implements PBGenerationService { + @override + PBContext currentContext; + + PBConstraintGenerationService({this.currentContext}); + + /// Traverse to the bottom of the tree, and implement constraints to nodes that don't already contain it such as [InjectedContainer] and then work our way up the tree. + /// Through Traversal, discover whether there are elements that will conflict on scaling, if so, change the layout to a Stack. + PBIntermediateTree implementConstraints(PBIntermediateTree tree) { + if (tree.rootNode == null) { + return tree; + } + + for (var node + in tree.where((element) => element != null).toList().reversed) { + // if (node is PBLayoutIntermediateNode) { + if (node.children.length > 1) { + /// Inherit Constraints from all the children of this layout. + node.children + .where((element) => element != null) + .toList() + .forEach((element) { + node.constraints = _inheritConstraintsFromChild( + constraints: node.constraints ?? + PBIntermediateConstraints( + pinTop: false, + pinBottom: false, + pinLeft: false, + pinRight: false, + ), + childConstraints: element.constraints); + }); + if (node is PBLayoutIntermediateNode) { + if (_shouldLayoutBeStack(node)) { + /// Change Layout to Stack + var newStackReplacement = + PBIntermediateStackLayout(node.UUID, node.name); + node.attributes.forEach((element) { + newStackReplacement.addAttribute(element); + }); + newStackReplacement.constraints = node.constraints; + node = newStackReplacement; + } + } + } + if (node.constraints == null) { + if (node.child?.constraints == null) { + print( + "Constraint Inheritance could not be performed because child's constraints were null"); + } else { + node.constraints = node.child.constraints; + } + } + } + return tree; + } + + /// Go through children and find out if there's a node that will overlap another node when scaling. + bool _shouldLayoutBeStack(PBLayoutIntermediateNode node) { + if (node is PBIntermediateStackLayout) { + return false; + } else if (node is PBIntermediateColumnLayout) { + var res = _isVerticalOverlap(node); + print(res); + return res; + } else if (node is PBIntermediateRowLayout) { + var res = _isHorizontalOverlap(node); + print(res); + return res; + } else { + print( + 'This constraint generation service does not support this layout: ${node.runtimeType}'); + return false; + } + } + + bool _isHorizontalOverlap(PBLayoutIntermediateNode node) { + var lastLeftPinIndex = -1; + var lastRightPinIndex = -1; + var isOverlap = false; + node.children.asMap().forEach((key, value) { + if (value.constraints.pinLeft) { + if (key - 1 != lastLeftPinIndex) { + isOverlap = true; + } else { + lastLeftPinIndex = key; + } + } + }); + + if (isOverlap) { + return isOverlap; + } + + node.children.reversed.toList().asMap().forEach((key, value) { + /// Needs to be reversed. + if (value.constraints.pinRight) { + if (key - 1 != lastRightPinIndex) { + isOverlap = true; + } else { + lastRightPinIndex = key; + } + } + }); + return isOverlap; + } + + bool _isVerticalOverlap(PBLayoutIntermediateNode node) { + var lastTopPinIndex = -1; + var lastBottomPinIndex = -1; + var isOverlap = false; + node.children.asMap().forEach((key, value) { + if (value.constraints.pinTop) { + if (key - 1 != lastTopPinIndex) { + isOverlap = true; + } else { + lastTopPinIndex = key; + } + } + }); + + if (isOverlap) { + return isOverlap; + } + + node.children.reversed.toList().asMap().forEach((key, value) { + if (value.constraints.pinBottom) { + if (key - 1 != lastBottomPinIndex) { + isOverlap = true; + } else { + lastBottomPinIndex = key; + } + } + }); + return isOverlap; + } + + PBIntermediateConstraints _inheritConstraintsFromChild( + {PBIntermediateConstraints constraints, + PBIntermediateConstraints childConstraints}) { + if (childConstraints.pinLeft) { + constraints.pinLeft = true; + } + if (childConstraints.pinRight) { + constraints.pinRight = true; + } + if (childConstraints.pinTop) { + constraints.pinTop = true; + } + if (childConstraints.pinBottom) { + constraints.pinBottom = true; + } + if (childConstraints.fixedHeight != null) { + if (constraints.fixedHeight == null) { + constraints.fixedHeight = childConstraints.fixedHeight; + } else if (constraints.fixedHeight < childConstraints.fixedHeight) { + constraints.fixedHeight = childConstraints.fixedHeight; + } + } + if (childConstraints.fixedWidth != null) { + if (constraints.fixedWidth == null) { + constraints.fixedWidth = childConstraints.fixedWidth; + } else if (constraints.fixedWidth < childConstraints.fixedWidth) { + constraints.fixedWidth = childConstraints.fixedWidth; + } + } + return constraints; + } +} diff --git a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart index 606ab3da..0f04f869 100644 --- a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart +++ b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart @@ -1,5 +1,4 @@ import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/directed_state_graph.dart'; class IntermediateAuxiliaryData { @@ -8,9 +7,6 @@ class IntermediateAuxiliaryData { /// Info relating to a elements borders, currently just in a map format. Map borderInfo; - /// Info relating to the alignment of an element, currently just in a map format. - Map alignment; - /// The background color of the element. String color; @@ -19,7 +15,6 @@ class IntermediateAuxiliaryData { IntermediateAuxiliaryData({ this.stateGraph, - this.alignment, this.color, }) { stateGraph ??= DirectedStateGraph(); From 595779cfbaa8852fa8941615ea874ca565c70583 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 17 Jun 2021 16:41:02 -0600 Subject: [PATCH 220/404] Only add imports if they are not null to platform builder --- .../pb_generation_configuration.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 71ecd7ae..a697d632 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -219,7 +219,10 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var imports = {}; platformOrientationMap.forEach((key, map) { map.forEach((key, tree) { - imports.addAll(_importProcessor.getImport(tree.UUID)); + var tempImports = _importProcessor.getImport(tree.UUID); + if (tempImports != null) { + imports.addAll(tempImports); + } }); }); return imports; From 71cc4438276850c9670659103b7c043e8daeaf5c Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 17 Jun 2021 19:04:28 -0400 Subject: [PATCH 221/404] Log to Sentry if import is null in PBGenConfig --- .../pb_generation_configuration.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index a697d632..2ece0455 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/command_gen_middleware.dart'; @@ -219,9 +220,14 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { var imports = {}; platformOrientationMap.forEach((key, map) { map.forEach((key, tree) { - var tempImports = _importProcessor.getImport(tree.UUID); - if (tempImports != null) { - imports.addAll(tempImports); + var uuidImport = _importProcessor.getImport(tree.UUID); + if (uuidImport == null) { + MainInfo().sentry.captureException( + exception: Exception( + 'Import for tree with UUID ${tree.UUID} was null when getting imports from processor.')); + print('buffer'); + } else { + imports.addAll(_importProcessor.getImport(tree.UUID)); } }); }); From 8cb39bac078041ec77c43ca6b46add51464d7296 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 17 Jun 2021 19:06:06 -0400 Subject: [PATCH 222/404] Remove buffer statement --- .../generation_configuration/pb_generation_configuration.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 2ece0455..89f758f2 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -225,7 +225,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { MainInfo().sentry.captureException( exception: Exception( 'Import for tree with UUID ${tree.UUID} was null when getting imports from processor.')); - print('buffer'); } else { imports.addAll(_importProcessor.getImport(tree.UUID)); } From fceab129c738904f3bd8244271b9ba4a65d1ae99 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 17 Jun 2021 17:28:10 -0600 Subject: [PATCH 223/404] Make tree names be the same kind of case --- .../services/pb_platform_orientation_linker_service.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 31839357..9bd93455 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -1,5 +1,5 @@ import 'dart:collection'; - +import 'package:recase/recase.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; @@ -66,12 +66,12 @@ class PBPlatformOrientationLinkerService { var trees = _map[key]; for (var currTree in trees) { var treeName = key; - var iterTreeName = currTree.rootNode.name; + var iterTreeName = currTree.rootNode.name.snakeCase; if (treeName == iterTreeName && tree.data.orientation == currTree.data.orientation && tree.data.platform == currTree.data.platform) { // Rename the tree if both trees have the same orientation and platform - tree.rootNode.name = treeName + '_${_mapCounter[tree.rootNode.name]}'; + tree.rootNode.name = treeName + '_${_mapCounter[iterTreeName]}'; _mapCounter[treeName]++; } } From 6ee3f2a6d7ebd3e3c2b5c35f59e40dafa020d67e Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 17 Jun 2021 19:28:29 -0400 Subject: [PATCH 224/404] Fixed incorrect comparison of strings in pb platform orientation linker --- .../services/pb_platform_orientation_linker_service.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 31839357..25d77c55 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'package:recase/recase.dart'; class PBPlatformOrientationLinkerService { static final PBPlatformOrientationLinkerService _pbPlatformLinkerService = @@ -65,8 +66,9 @@ class PBPlatformOrientationLinkerService { // Check if we have exact trees (same orientation and platform) var trees = _map[key]; for (var currTree in trees) { - var treeName = key; - var iterTreeName = currTree.rootNode.name; + // Ensure we're comparing the same string by converting to snakecase + var treeName = key.snakeCase; + var iterTreeName = currTree.rootNode.name.snakeCase; if (treeName == iterTreeName && tree.data.orientation == currTree.data.orientation && tree.data.platform == currTree.data.platform) { From 28f186c5f7b939ed6c1d08935d310c34ef03a924 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Fri, 18 Jun 2021 18:12:06 -0400 Subject: [PATCH 225/404] Added null-check for platform instance --- .../pb_generation_configuration.dart | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index def13872..9b6e7c66 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -208,11 +208,14 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ResponsiveLayoutBuilderCommand.NAME_TO_RESPONSIVE_LAYOUT, )); + // TODO: Find a more effective way to do this, since there are a lot + // of assumptions happening in the code. var newCommand = generatePlatformInstance( platformsMap, screenName, fileStructureStrategy, rawImports); - fileStructureStrategy.commandCreated(newCommand); - setMainForPlatform(newCommand, screenName); + if (newCommand != null) { + setMainForPlatform(newCommand, screenName); + } }); } @@ -239,7 +242,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { /// This method takes a command and checks if one of its child screens /// is the home screen for the project, if so modify main /// to redirect to the proper builder - bool setMainForPlatform(var newCommand, String screenName) { + bool setMainForPlatform(WriteScreenCommand newCommand, String screenName) { var platformOrientationMap = poLinker.getPlatformOrientationData(screenName); @@ -248,10 +251,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { if (tree.rootNode is InheritedScaffold && (tree.rootNode as InheritedScaffold).isHomeScreen) { fileStructureStrategy.commandCreated(EntryFileCommand( - entryScreenName: (newCommand as WriteScreenCommand) - .name - .replaceAll('.dart', '') - .pascalCase, + entryScreenName: + newCommand.name.replaceAll('.dart', '').pascalCase, entryScreenImport: _importProcessor .getFormattedImports(newCommand.UUID, importMapper: (import) => From ca6bf43b2f3e98be4607875941a3252e47dcf475 Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Fri, 18 Jun 2021 22:18:30 -0600 Subject: [PATCH 226/404] Fixed Padding & Sizing Generation Bugs --- .../attribute-helper/pb_size_helper.dart | 4 ++-- .../visual-widgets/pb_padding_gen.dart | 16 ++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index b3804039..256b2154 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -43,10 +43,10 @@ class PBSizeHelper extends PBAttributesHelper { if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { var height = source.constraints.fixedHeight != null ? body['height'].toStringAsFixed(3) - : 'MediaQuery.of(context).size.height * ${relativeHeight.toStringAsFixed(3)},'; + : 'MediaQuery.of(context).size.height * ${relativeHeight.toStringAsFixed(3)}'; var width = source.constraints.fixedWidth != null ? body['width'].toStringAsFixed(3) - : 'MediaQuery.of(context).size.width * ${relativeWidth.toStringAsFixed(3)},'; + : 'MediaQuery.of(context).size.width * ${relativeWidth.toStringAsFixed(3)}'; buffer.write( 'constraints: BoxConstraints(maxHeight: ${height}, maxWidth: ${width}),'); diff --git a/lib/generation/generators/visual-widgets/pb_padding_gen.dart b/lib/generation/generators/visual-widgets/pb_padding_gen.dart index 1c7d7bb7..511c5bc0 100644 --- a/lib/generation/generators/visual-widgets/pb_padding_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_padding_gen.dart @@ -20,11 +20,15 @@ class PBPaddingGen extends PBGenerator { : 'Width') + ' * $fixedValue'; } - return 'MediaQuery.of(context).size.' + - (paddingPosition.item1 == 'top' || paddingPosition.item1 == 'bottom' - ? 'height' - : 'width') + - ' * $fixedValue'; + if (paddingPosition.item2) { + return '$fixedValue'; + } else { + return 'MediaQuery.of(context).size.' + + (paddingPosition.item1 == 'top' || paddingPosition.item1 == 'bottom' + ? 'height' + : 'width') + + ' * $fixedValue'; + } } @override @@ -65,7 +69,7 @@ class PBPaddingGen extends PBGenerator { for (var position in paddingPositions) { if (reflectedPadding.getField(Symbol(position.item1)).reflectee != 0) { buffer.write( - '$position: ${relativePadding(source.generator.templateStrategy, reflectedPadding.getField(Symbol(position.item1)).reflectee, position)},'); + '${position.item1}: ${relativePadding(source.generator.templateStrategy, reflectedPadding.getField(Symbol(position.item1)).reflectee, position)},'); } } From 8426643df79b7f0e2e3f0adbf7bfbde34fc6522e Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 24 Jun 2021 15:50:22 -0600 Subject: [PATCH 227/404] Only do padding ig the screen width or height is greater than 0 --- .../entities/alignments/padding.dart | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index fa67b3d3..5bff5b8d 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -5,7 +5,6 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class Padding extends PBVisualIntermediateNode { - double left, right, top, bottom, screenWidth, screenHeight; @override @@ -55,23 +54,26 @@ class Padding extends PBVisualIntermediateNode { /// Calculating the percentage of the padding in relation to the [screenHeight] and the [screenWidth]. /// FIXME: creating a lifecyle between the [PBGenerator] and the [PBIntermediateNode] where it provides a callback that /// executes just before the generator generates the code for the [PBIntermediateNode]. - screenHeight = screenHeight == 0 ? 1 : screenHeight; - screenWidth = screenWidth == 0 ? 1 : screenWidth; - if (left != null) { - left = (left / screenWidth); - left = left < 0.01 ? null : left; - } - if (right != null) { - right = right / screenWidth; - right = right < 0.01 ? null : right; - } - if (top != null) { - top = top / screenHeight; - top = top < 0.01 ? null : top; + + if (screenWidth > 0) { + if (left != null) { + left = (left / screenWidth); + left = left < 0.01 ? null : left; + } + if (right != null) { + right = right / screenWidth; + right = right < 0.01 ? null : right; + } } - if (bottom != null) { - bottom = bottom / screenHeight; - bottom = bottom < 0.01 ? null : bottom; + if (screenWidth > 0) { + if (top != null) { + top = top / screenHeight; + top = top < 0.01 ? null : top; + } + if (bottom != null) { + bottom = bottom / screenHeight; + bottom = bottom < 0.01 ? null : bottom; + } } } From f67eed2c016214aa2aec42c05c24f70d10dc9cfa Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 24 Jun 2021 15:50:41 -0600 Subject: [PATCH 228/404] Add media query to body on scaffold --- lib/generation/generators/layouts/pb_scaffold_gen.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/generation/generators/layouts/pb_scaffold_gen.dart b/lib/generation/generators/layouts/pb_scaffold_gen.dart index 004b969d..abab02c5 100644 --- a/lib/generation/generators/layouts/pb_scaffold_gen.dart +++ b/lib/generation/generators/layouts/pb_scaffold_gen.dart @@ -39,6 +39,7 @@ class PBScaffoldGenerator extends PBGenerator { } if (body != null) { + generatorContext.sizingContext = SizingValueContext.MediaQueryValue; // hack to pass screen width and height to the child buffer.write('body: '); var bodyStr = body.generator.generate(body, generatorContext); From c1f2db23511f208b9fe687b37092053abf5d670b Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Tue, 13 Jul 2021 21:39:22 -0500 Subject: [PATCH 229/404] Temp Commit --- lib/configurations/configurations.json | 2 +- lib/controllers/interpret.dart | 1 - lib/design_logic/text.dart | 2 + lib/eggs/injected_app_bar.dart | 4 +- lib/eggs/injected_tab_bar.dart | 2 +- .../attribute-helper/pb_size_helper.dart | 4 ++ .../generators/layouts/pb_scaffold_gen.dart | 5 +- .../visual-widgets/pb_bitmap_gen.dart | 7 +-- .../alignments/injected_positioned.dart | 4 +- .../entities/inherited_circle.dart | 8 ++-- .../entities/inherited_container.dart | 10 ++-- .../entities/inherited_scaffold.dart | 47 ++++++++++++++----- .../entities/injected_container.dart | 10 ++-- .../entities/layouts/stack.dart | 20 ++++---- .../entities/pb_shared_instance.dart | 9 ++-- .../entities/pb_shared_master_node.dart | 43 ++++++++--------- .../pb_intermediate_constraints.dart | 8 ++-- .../pb_constraint_generation_service.dart | 14 ++++-- .../pb_layout_generation_service.dart | 23 +++++---- pubspec.yaml | 2 +- .../padding_dynamic_size_test.dart | 14 +++--- .../services/interpret_test.dart | 2 +- 22 files changed, 145 insertions(+), 96 deletions(-) diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index fc3455bc..39805d2b 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -7,7 +7,7 @@ "row", "stack" ], - "state-management": "none", + "state-management": "provider", "breakpoints": { "mobile": 360, "tablet": 600, diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 8192f6b3..3c4b145f 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -123,7 +123,6 @@ class Interpret { var stopwatch2 = Stopwatch()..start(); /// LayoutGenerationService - intermediateTree.rootNode = await layoutGenerationService( intermediateTree.rootNode, currentContext, stopwatch2); diff --git a/lib/design_logic/text.dart b/lib/design_logic/text.dart index 03c39b8d..80a24755 100644 --- a/lib/design_logic/text.dart +++ b/lib/design_logic/text.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/design_logic/pb_style.dart'; import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -119,6 +120,7 @@ class Text extends DesignElement implements DesignNodeFactory, DesignNode { name, Uuid().v4(), currentContext: currentContext, + constraints: PBIntermediateConstraints(), )..addChild( InheritedText(this, name, currentContext: currentContext), )); diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index e8ad9d2b..d439e874 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -72,7 +72,7 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { /// This align only modifies middleItem var tempNode = InjectedContainer(middleItem.bottomRightCorner, middleItem.topLeftCorner, middleItem.name, middleItem.UUID, - currentContext: currentContext) + currentContext: currentContext, constraints: middleItem.constraints) ..addChild(middleItem); getAttributeNamed('title').attributeNode = tempNode; @@ -100,7 +100,7 @@ class PBAppBarGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext generatorContext) { - generatorContext.sizingContext = SizingValueContext.PointValue; + // generatorContext.sizingContext = SizingValueContext.PointValue; if (source is InjectedAppbar) { var buffer = StringBuffer(); diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index b4a9d6bd..b2a77f55 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -74,7 +74,7 @@ class PBTabBarGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext generatorContext) { - generatorContext.sizingContext = SizingValueContext.PointValue; + // generatorContext.sizingContext = SizingValueContext.PointValue; if (source is InjectedTabBar) { var tabs = source.tabs; diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index 256b2154..5b14d47a 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -40,6 +40,10 @@ class PBSizeHelper extends PBAttributesHelper { ? relativeWidth / screenWidth : relativeWidth; + if (source.currentContext.tree.first.name == 'ArtboardBRpinfixedwidth') { + print('asdf'); + } + if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { var height = source.constraints.fixedHeight != null ? body['height'].toStringAsFixed(3) diff --git a/lib/generation/generators/layouts/pb_scaffold_gen.dart b/lib/generation/generators/layouts/pb_scaffold_gen.dart index f703a699..aff0031b 100644 --- a/lib/generation/generators/layouts/pb_scaffold_gen.dart +++ b/lib/generation/generators/layouts/pb_scaffold_gen.dart @@ -25,14 +25,14 @@ class PBScaffoldGenerator extends PBGenerator { } if (appBar != null) { buffer.write('appBar: '); - generatorContext.sizingContext = SizingValueContext.PointValue; + // generatorContext.sizingContext = SizingValueContext.PointValue; var appbarStr = appBar.generator.generate(appBar, generatorContext); buffer.write('$appbarStr,\n'); } if (bottomNavBar != null) { buffer.write('bottomNavigationBar: '); - generatorContext.sizingContext = SizingValueContext.PointValue; + // generatorContext.sizingContext = SizingValueContext.PointValue; var navigationBar = bottomNavBar.generator.generate(bottomNavBar, generatorContext); buffer.write('$navigationBar, \n'); @@ -41,6 +41,7 @@ class PBScaffoldGenerator extends PBGenerator { if (body != null) { // hack to pass screen width and height to the child buffer.write('body: '); + // generatorContext.sizingContext = SizingValueContext.ScaleValue; var bodyStr = body.generator.generate(body, generatorContext); buffer.write('$bodyStr, \n'); } diff --git a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart index b868a998..d7070451 100644 --- a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart @@ -22,9 +22,10 @@ class PBBitmapGenerator extends PBGenerator { } else if (SN_UUIDtoVarName.containsKey('${source.UUID}_layerStyle')) { buffer.write('${SN_UUIDtoVarName[source.UUID + '_layerStyle']} ?? '); } + // buffer.write( + // '\'assets/${source is InheritedBitmap ? source.referenceImage : ('images/' + source.UUID + '.png')}\', ${_sizehelper.generate(source, generatorContext)})'); buffer.write( - '\'assets/${source is InheritedBitmap ? source.referenceImage : ('images/' + source.UUID + '.png')}\', ${_sizehelper.generate(source, generatorContext)})'); + '\'assets/${source is InheritedBitmap ? source.referenceImage : ('images/' + source.UUID + '.png')}\')'); return buffer.toString(); } -} - +} \ No newline at end of file diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index ba892e31..8ba528bc 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_positioned_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -18,8 +19,9 @@ class InjectedPositioned extends PBIntermediateNode this.UUID, { this.valueHolder, this.currentContext, + PBIntermediateConstraints constraints, }) : super(Point(0, 0), Point(0, 0), UUID, '', - currentContext: currentContext) { + currentContext: currentContext, constraints: constraints) { generator = PBPositionedGenerator(); } diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index ca50c8ae..46026009 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -55,10 +55,10 @@ class InheritedCircle extends PBVisualIntermediateNode @override void alignChild() { var padding = Padding('', child.constraints, - left: child.topLeftCorner.x - topLeftCorner.x, - right: bottomRightCorner.x - child.bottomRightCorner.x, - top: child.topLeftCorner.y - topLeftCorner.y, - bottom: child.bottomRightCorner.y - bottomRightCorner.y, + left: (child.topLeftCorner.x - topLeftCorner.x).abs(), + right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), + top: (child.topLeftCorner.y - topLeftCorner.y).abs(), + bottom: (child.bottomRightCorner.y - bottomRightCorner.y).abs(), topLeftCorner: topLeftCorner, bottomRightCorner: bottomRightCorner, currentContext: currentContext); diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 7d94408c..5ae7c407 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -85,10 +85,12 @@ class InheritedContainer extends PBVisualIntermediateNode if (child != null) { /// Refactor to child.constraints != null if (child is! InheritedText) { - var left = child.topLeftCorner.x - topLeftCorner.x ?? 0.0; - var right = bottomRightCorner.x - child.bottomRightCorner.x ?? 0.0; - var top = child.topLeftCorner.y - topLeftCorner.y ?? 0.0; - var bottom = child.bottomRightCorner.y - bottomRightCorner.y ?? 0.0; + var left = (child.topLeftCorner.x - topLeftCorner.x).abs() ?? 0.0; + var right = + (bottomRightCorner.x - child.bottomRightCorner.x).abs() ?? 0.0; + var top = (child.topLeftCorner.y - topLeftCorner.y).abs() ?? 0.0; + var bottom = + (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0; var padding = Padding('', child.constraints, left: left, right: right, diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index f5cff0d1..e29202d1 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; @@ -109,26 +110,48 @@ class InheritedScaffold extends PBVisualIntermediateNode if (child is TempGroupLayoutNode) { child.addChild(node); return; - } - // If there's multiple children add a temp group so that layout service lays the children out. - if (child != null) { - var temp = TempGroupLayoutNode(null, currentContext, node.name); - temp.addChild(child); - temp.addChild(node); - child = temp; } else { - child = node; + if (child != null) { + child.addChild(node); + } else { + var stack = PBIntermediateStackLayout( + node.name, + '', + currentContext: currentContext, + ); + stack.addChild(node); + child = stack; + } } + // If there's multiple children add a temp group so that layout service lays the children out. + // if (child != null) { + // var temp = TempGroupLayoutNode(null, currentContext, node.name); + // temp.addChild(child); + // temp.addChild(node); + // child = temp; + // } else { + // child = node; + // } } @override void alignChild() { if (child != null) { + // if (child is! PBIntermediateStackLayout) { + // var stack = PBIntermediateStackLayout( + // '', + // '', + // currentContext: currentContext, + // ); + // stack.addChild(child); + // child = stack; + // } + var padding = Padding('', child.constraints, - left: child.topLeftCorner.x - topLeftCorner.x, - right: bottomRightCorner.x - child.bottomRightCorner.x, - top: child.topLeftCorner.y - topLeftCorner.y, - bottom: child.bottomRightCorner.y - bottomRightCorner.y, + left: (child.topLeftCorner.x - topLeftCorner.x).abs(), + right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), + top: (child.topLeftCorner.y - topLeftCorner.y).abs(), + bottom: (bottomRightCorner.y - child.bottomRightCorner.y).abs(), topLeftCorner: topLeftCorner, bottomRightCorner: bottomRightCorner, currentContext: currentContext); diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 79c8dcc5..05678e94 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -1,5 +1,3 @@ -import 'dart:ffi'; - import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; @@ -55,10 +53,10 @@ class InjectedContainer extends PBVisualIntermediateNode void alignChild() { /// Add Padding that takes into account pinning (hard values). var padding = Padding('', child.constraints, - left: child.topLeftCorner.x - topLeftCorner.x, - right: bottomRightCorner.x - child.bottomRightCorner.x, - top: child.topLeftCorner.y - topLeftCorner.y, - bottom: child.bottomRightCorner.y - bottomRightCorner.y, + left: (child.topLeftCorner.x - topLeftCorner.x).abs(), + right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), + top: (child.topLeftCorner.y - topLeftCorner.y).abs(), + bottom: (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0, topLeftCorner: topLeftCorner, bottomRightCorner: bottomRightCorner, currentContext: currentContext); diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 5f8d75cd..8868e934 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -54,16 +54,16 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { left = child.topLeftCorner.x - topLeftCorner.x; right = bottomRightCorner.x - child.bottomRightCorner.x; - alignedChildren.add(InjectedPositioned( - Uuid().v4(), - valueHolder: PositionedValueHolder( - top: top, - bottom: bottom, - left: left, - right: right, - ), - currentContext: currentContext, - )..addChild(child)); + alignedChildren.add(InjectedPositioned(Uuid().v4(), + valueHolder: PositionedValueHolder( + top: top, + bottom: bottom, + left: left, + right: right, + ), + currentContext: currentContext, + constraints: child.constraints) + ..addChild(child)); } replaceChildren(alignedChildren); } diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 9461fc09..d4dbbcc8 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -80,10 +80,11 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode void alignChild() { if (child != null) { var padding = Padding('', child.constraints, - left: child.topLeftCorner.x - topLeftCorner.x, - right: bottomRightCorner.x - child.bottomRightCorner.x, - top: child.topLeftCorner.y - topLeftCorner.y, - bottom: child.bottomRightCorner.y - bottomRightCorner.y, + left: (child.topLeftCorner.x - topLeftCorner.x).abs(), + right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), + top: (child.topLeftCorner.y - topLeftCorner.y).abs(), + bottom: + (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0, topLeftCorner: topLeftCorner, bottomRightCorner: bottomRightCorner, currentContext: currentContext); diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 40bd6358..98c1b84a 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -86,26 +86,24 @@ class PBSharedMasterNode extends PBVisualIntermediateNode this.currentContext.screenTopLeftCorner = Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y); - parametersDefinition = overridableProperties - .map((p) { - var PBSymMasterP = PBSymbolMasterParameter( - p._friendlyName, - p.type, - p.UUID, - p.canOverride, - p.propertyName, - /* Removed Parameter Definition as it was accepting JSON?*/ - null, // TODO: @Eddie - currentContext.screenTopLeftCorner.x, - currentContext.screenTopLeftCorner.y, - currentContext.screenBottomRightCorner.x, - currentContext.screenBottomRightCorner.y, - context: currentContext); - parametersDefsMap[p.propertyName] = PBSymMasterP; - return PBSymMasterP; }) - .toList() - ..removeWhere((p) => p == null || p.parameterDefinition == null); - + parametersDefinition = overridableProperties.map((p) { + var PBSymMasterP = PBSymbolMasterParameter( + p._friendlyName, + p.type, + p.UUID, + p.canOverride, + p.propertyName, + /* Removed Parameter Definition as it was accepting JSON?*/ + null, // TODO: @Eddie + currentContext.screenTopLeftCorner.x, + currentContext.screenTopLeftCorner.y, + currentContext.screenBottomRightCorner.x, + currentContext.screenBottomRightCorner.y, + context: currentContext); + parametersDefsMap[p.propertyName] = PBSymMasterP; + return PBSymMasterP; + }).toList() + ..removeWhere((p) => p == null || p.parameterDefinition == null); } @override @@ -136,7 +134,10 @@ class PBSharedParameterProp { dynamic get initialValue => _initialValue; final String _friendlyName; - String get friendlyName => _friendlyName ?? SN_UUIDtoVarName[PBInputFormatter.findLastOf(propertyName, '/')] ?? 'noname'; + String get friendlyName => + _friendlyName ?? + SN_UUIDtoVarName[PBInputFormatter.findLastOf(propertyName, '/')] ?? + 'noname'; PBSharedParameterProp(this._friendlyName, this._type, this.value, this._canOverride, this._propertyName, this._UUID, this._initialValue); diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart index 11b78f8e..c674c8f3 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart @@ -14,10 +14,10 @@ class PBIntermediateConstraints { PBIntermediateConstraints.fromConstraints( PBDLConstraints constraints, double height, double width) { - pinLeft = constraints.pinLeft; - pinRight = constraints.pinRight; - pinTop = constraints.pinTop; - pinBottom = constraints.pinBottom; + pinLeft = constraints.pinLeft ?? false; + pinRight = constraints.pinRight ?? false; + pinTop = constraints.pinTop ?? false; + pinBottom = constraints.pinBottom ?? false; if (constraints.fixedHeight) { fixedHeight = height; } diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index ee879e7f..e201703f 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -27,8 +28,8 @@ class PBConstraintGenerationService implements PBGenerationService { for (var node in tree.where((element) => element != null).toList().reversed) { - // if (node is PBLayoutIntermediateNode) { - if (node.children.length > 1) { + if (node is PBLayoutIntermediateNode) { + // if (node.children.isNotEmpty) { /// Inherit Constraints from all the children of this layout. node.children .where((element) => element != null) @@ -59,8 +60,15 @@ class PBConstraintGenerationService implements PBGenerationService { } if (node.constraints == null) { if (node.child?.constraints == null) { + // if (node.child != null) { print( - "Constraint Inheritance could not be performed because child's constraints were null"); + "Constraint Inheritance could not be performed because child's constraints were null for class type: [${node.runtimeType}]"); + // } + if (node is! InheritedText) { + print('asdf'); + } else { + node.constraints = PBIntermediateConstraints(); + } } else { node.constraints = node.child.constraints; } diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index b4c0678c..0025e331 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -31,7 +31,7 @@ class PBLayoutGenerationService implements PBGenerationService { ///[LayoutRule] that check post conditions. final List _postLayoutRules = [ StackReductionVisualRule(), - ContainerPostRule(), + // ContainerPostRule(), ContainerConstraintRule() ]; @@ -44,13 +44,13 @@ class PBLayoutGenerationService implements PBGenerationService { PBLayoutGenerationService({this.currentContext}) { var layoutHandlers = { - 'column': PBIntermediateColumnLayout( - '', - currentContext: currentContext, - UUID: Uuid().v4(), - ), - 'row': PBIntermediateRowLayout('', Uuid().v4(), - currentContext: currentContext), + // 'column': PBIntermediateColumnLayout( + // '', + // currentContext: currentContext, + // UUID: Uuid().v4(), + // ), + // 'row': PBIntermediateRowLayout('', Uuid().v4(), + // currentContext: currentContext), 'stack': PBIntermediateStackLayout('', Uuid().v4(), currentContext: currentContext), }; @@ -152,7 +152,8 @@ class PBLayoutGenerationService implements PBGenerationService { : _replaceNode( tempGroup, InjectedContainer(tempGroup.bottomRightCorner, - tempGroup.topLeftCorner, tempGroup.name, tempGroup.UUID)); + tempGroup.topLeftCorner, tempGroup.name, tempGroup.UUID, + constraints: tempGroup.constraints)); } return tempGroup; } @@ -217,6 +218,10 @@ class PBLayoutGenerationService implements PBGenerationService { } parent.replaceChildren(children); if (children.length == 1) { + /// With the support for scaling & pinning, Stacks are now responsible for positioning. + // if (parent is PBIntermediateStackLayout) { + // return parent; + // } return _replaceNode(parent, children[0]); } else { return parent is! TempGroupLayoutNode diff --git a/pubspec.yaml b/pubspec.yaml index 34285632..26aebba5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: logger: ^0.8.3 uuid: ^2.1.0 quick_log: ^1.1.3 - sentry: ">=3.0.0 <4.0.0" + sentry: ^5.1.0 http2: ^1.0.1 recase: "^3.0.0" tuple: ^1.0.3 diff --git a/test/lib/input_services/padding_dynamic_size_test.dart b/test/lib/input_services/padding_dynamic_size_test.dart index ec015f0c..c5625f4e 100644 --- a/test/lib/input_services/padding_dynamic_size_test.dart +++ b/test/lib/input_services/padding_dynamic_size_test.dart @@ -26,12 +26,14 @@ void main() { currentChild = NodeMock(); when(currentChild.currentContext).thenReturn(currentContext); - currentPadding = Padding(Uuid().v4(), - left: 15, - right: 15, - bottom: 15, - top: 15, - currentContext: currentContext); + + ///TODO: Update padding test + // currentPadding = Padding(Uuid().v4(), + // left: 15, + // right: 15, + // bottom: 15, + // top: 15, + // currentContext: currentContext); }); test('Calculating dynamic padding size', () { currentPadding.addChild(currentChild); diff --git a/test/lib/interpret_and_optimize/services/interpret_test.dart b/test/lib/interpret_and_optimize/services/interpret_test.dart index b3293f4d..14e6a09d 100644 --- a/test/lib/interpret_and_optimize/services/interpret_test.dart +++ b/test/lib/interpret_and_optimize/services/interpret_test.dart @@ -130,7 +130,7 @@ void main() { expect(mainTree != null, true); expect(mainTree is PBProject, true); expect(mainTree.forest.first.rootNode is InheritedScaffold, true); - expect(mainTree.forest.first.rootNode.child is InjectedAlign, true); + // expect(mainTree.forest.first.rootNode.child is InjectedAlign, true); ///TODO: Check the type of the leaf node expect(mainTree.forest.first.rootNode.child.child != null, true); From 82d5e7896d4fbf2592c28f744a8a791091f7c8da Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sat, 17 Jul 2021 17:07:14 -0600 Subject: [PATCH 230/404] FIX the positional values. Some values needed to be using the correct ration, vertical mesurements need to use the ratio of (size / original_screen_height), same for horizontal. Finally, moved that calculation into the context for other generators to access. --- .../generators/layouts/pb_scaffold_gen.dart | 2 +- .../visual-widgets/pb_positioned_gen.dart | 45 ++++++++++--------- .../helpers/pb_context.dart | 16 +++++++ 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/lib/generation/generators/layouts/pb_scaffold_gen.dart b/lib/generation/generators/layouts/pb_scaffold_gen.dart index ff438680..cf672ca8 100644 --- a/lib/generation/generators/layouts/pb_scaffold_gen.dart +++ b/lib/generation/generators/layouts/pb_scaffold_gen.dart @@ -39,7 +39,7 @@ class PBScaffoldGenerator extends PBGenerator { } if (body != null) { - generatorContext.sizingContext = SizingValueContext.MediaQueryValue; + generatorContext.sizingContext = SizingValueContext.ScaleValue; // hack to pass screen width and height to the child buffer.write('body: '); // generatorContext.sizingContext = SizingValueContext.ScaleValue; diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 8c5e0ecf..d1ac4d95 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -25,21 +25,28 @@ class PBPositionedGenerator extends PBGenerator { right: source.valueHolder.right, ); + valueHolder.left = + source.currentContext.getRatioPercentage(source.valueHolder.left); + valueHolder.right = + source.currentContext.getRatioPercentage(source.valueHolder.right); + valueHolder.top = source.currentContext + .getRatioPercentage(source.valueHolder.top, false); + valueHolder.bottom = source.currentContext + .getRatioPercentage(source.valueHolder.bottom, false); + if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { multStringH = 'MediaQuery.of(context).size.width * '; multStringV = 'MediaQuery.of(context).size.height *'; - _calculateRelativeValues(source, valueHolder); } else if (generatorContext.sizingContext == SizingValueContext.LayoutBuilderValue) { - _calculateRelativeValues(source, valueHolder); multStringH = 'constraints.maxWidth * '; multStringV = 'constraints.maxHeight * '; } buffer.write( - 'left: $multStringH${valueHolder.left.toStringAsFixed(3)}, right: $multStringH${valueHolder.right.toStringAsFixed(3)},'); + 'left: ${_normalizeValue(multStringH, valueHolder.left)}, right: ${_normalizeValue(multStringH, valueHolder.right)},'); buffer.write( - 'top: $multStringV${valueHolder.top.toStringAsFixed(3)}, bottom: $multStringV${valueHolder.bottom.toStringAsFixed(3)},'); + 'top: ${_normalizeValue(multStringH, valueHolder.top)}, bottom: ${_normalizeValue(multStringH, valueHolder.bottom)},'); try { source.child.currentContext = source.currentContext; @@ -58,24 +65,18 @@ class PBPositionedGenerator extends PBGenerator { } } - void _calculateRelativeValues( - InjectedPositioned source, PositionedValueHolder holder) { - if (source.currentContext?.screenTopLeftCorner?.x != null && - source.currentContext?.screenBottomRightCorner?.x != null) { - var screenWidth = ((source.currentContext?.screenTopLeftCorner?.x) - - (source.currentContext?.screenBottomRightCorner?.x)) - .abs(); - holder.left = source.valueHolder.left / screenWidth; - holder.right = source.valueHolder.right / screenWidth; - } - - if (source.currentContext?.screenTopLeftCorner?.y != null && - source.currentContext?.screenBottomRightCorner?.y != null) { - var screenHeight = ((source.currentContext.screenTopLeftCorner.y) - - (source.currentContext.screenBottomRightCorner.y)) - .abs(); - holder.top = source.valueHolder.top / screenHeight; - holder.bottom = source.valueHolder.bottom / screenHeight; + /// Going to return the value without the [preValueStatement] if the [value] + /// is equal to `0`. + /// + /// The main purpose of this is to prevent reduntant multiplication, for example, + /// ```dart + /// MediaQuery.of(context).size.height * 0.0 + /// ``` + /// Where it should be `0`. + String _normalizeValue(String preValueStatement, double value) { + if (value == 0) { + return '0'; } + return '$preValueStatement${value.toStringAsFixed(3)}'; } } diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 2e35597f..567d84df 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -1,3 +1,4 @@ +import 'package:build/build.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; @@ -5,6 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.da import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'package:path/path.dart'; class PBContext { final PBConfiguration configuration; @@ -26,6 +28,20 @@ class PBContext { tree.addDependent(dependent); } } + + /// Getting the correct ratio measurement in respect to the original [screenTopLeftCorner] + /// or the [screenBottomRightCorner] sizes. + /// + /// [isHorizontal] (default value is `false`) + /// represents if the ratio should be the Horizontal one or the Vertical one. + double getRatioPercentage(double size, [bool isHorizontal = false]){ + if(size == 0){ + return size; + } + var screenWidth = (screenBottomRightCorner.x - screenTopLeftCorner.x).abs(); + var screenHeight = (screenBottomRightCorner.y - screenTopLeftCorner.y).abs(); + return isHorizontal ? size / screenWidth : size / screenHeight; + } } enum SizingValueContext { From a6d72c48528f007e6f6446284d0c6a0830cfa3d5 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sat, 17 Jul 2021 21:58:41 -0600 Subject: [PATCH 231/404] WIP focus area on where the positioned should be calculating their values. --- .../entities/inherited_scaffold.dart | 22 ++++--------------- .../value_objects/point.dart | 10 +++++++++ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index e29202d1..11844df9 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -89,6 +89,8 @@ class InheritedScaffold extends PBVisualIntermediateNode if (node is PBSharedInstanceIntermediateNode) { if (node.originalRef.name.contains('')) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); + // currentContext.canvasTLC = Point(currentContext.canvasTLC.x, + // currentContext.canvasTLC.y - node.topLeftCorner.y); return; } if (node.originalRef.name.contains('')) { @@ -100,6 +102,8 @@ class InheritedScaffold extends PBVisualIntermediateNode if (node is InjectedAppbar) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); + // currentContext.canvasTLC = Point(currentContext.canvasTLC.x, + // currentContext.canvasTLC.y - node.topLeftCorner.y); return; } if (node is InjectedTabBar) { @@ -123,29 +127,11 @@ class InheritedScaffold extends PBVisualIntermediateNode child = stack; } } - // If there's multiple children add a temp group so that layout service lays the children out. - // if (child != null) { - // var temp = TempGroupLayoutNode(null, currentContext, node.name); - // temp.addChild(child); - // temp.addChild(node); - // child = temp; - // } else { - // child = node; - // } } @override void alignChild() { if (child != null) { - // if (child is! PBIntermediateStackLayout) { - // var stack = PBIntermediateStackLayout( - // '', - // '', - // currentContext: currentContext, - // ); - // stack.addChild(child); - // child = stack; - // } var padding = Padding('', child.constraints, left: (child.topLeftCorner.x - topLeftCorner.x).abs(), diff --git a/lib/interpret_and_optimize/value_objects/point.dart b/lib/interpret_and_optimize/value_objects/point.dart index a4ab757e..8133b291 100644 --- a/lib/interpret_and_optimize/value_objects/point.dart +++ b/lib/interpret_and_optimize/value_objects/point.dart @@ -38,4 +38,14 @@ class Point implements Comparable { } return false; } + /// calculates the distance given two [Point]s + /// + /// [isXAxis], which default to `true`, is a flag on which axis should + /// the calculation be done. + static double dist(Point TLC, Point BTC, [isXAxis = true]){ + if(TLC == null || BTC == null){ + throw NullThrownError(); + } + return isXAxis ? (BTC.x - TLC.x).abs() : (BTC.y - TLC.y).abs(); + } } From 1f24b6cace77c605f9a691a387967a094af544cc Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sat, 17 Jul 2021 22:00:10 -0600 Subject: [PATCH 232/404] REFACTORED the interpret class with a builder pattern to customize the algorithm and what services should run on the trees. --- lib/controllers/interpret.dart | 108 +++--------------- .../entities/layouts/stack.dart | 1 - .../helpers/pb_context.dart | 46 ++++++-- .../helpers/pb_state_management_linker.dart | 23 ++-- .../pb_alignment_generation_service.dart | 15 +-- .../pb_constraint_generation_service.dart | 11 +- .../services/pb_generation_service.dart | 66 ++++++++++- .../pb_layout_generation_service.dart | 20 ++-- .../services/pb_plugin_control_service.dart | 14 ++- .../pb_semantic_generation_service.dart | 2 +- .../pb_visual_generation_service.dart | 2 +- 11 files changed, 164 insertions(+), 144 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 3c4b145f..5f71907b 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -4,7 +4,6 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service import 'package:parabeac_core/input/helper/design_project.dart'; import 'package:parabeac_core/input/helper/design_page.dart'; import 'package:parabeac_core/input/helper/design_screen.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -12,6 +11,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_constraint_generation_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; @@ -111,31 +111,20 @@ class Interpret { if (intermediateTree.rootNode == null) { return intermediateTree; } + var aitServices = [ + PBPluginControlService().convertAndModifyPluginNodeTree, + PBLayoutGenerationService().extractLayouts, + PBConstraintGenerationService().implementConstraints, + PBAlignGenerationService().addAlignmentToLayouts + ]; + + var builder = AITServiceBuilder(currentContext, intermediateTree, aitServices) + .addTransformation((tree, context) { + print(tree.hashCode); + return Future.value(tree); + }); + return builder.build(); - /// - /// pre-layout generation service for plugin nodes. - /// NOTE Disabled Plugin Control Service for right now - /// - var stopwatch1 = Stopwatch()..start(); - intermediateTree.rootNode = await pluginService( - intermediateTree.rootNode, currentContext, stopwatch1); - - var stopwatch2 = Stopwatch()..start(); - - /// LayoutGenerationService - intermediateTree.rootNode = await layoutGenerationService( - intermediateTree.rootNode, currentContext, stopwatch2); - - var stopwatch3 = Stopwatch()..start(); - - intermediateTree = await PBConstraintGenerationService() - .implementConstraints(intermediateTree); - - /// AlignGenerationService - intermediateTree.rootNode = await alignGenerationService( - intermediateTree.rootNode, currentContext, stopwatch3); - - return intermediateTree; } // TODO: refactor this method and/or `getIntermediateTree` @@ -164,74 +153,5 @@ class Interpret { return node; } - Future pluginService( - PBIntermediateNode parentnode, var context, var stopwatch1) async { - PBIntermediateNode node; - try { - node = PBPluginControlService(parentnode, currentContext: context) - .convertAndModifyPluginNodeTree(); - } catch (e, stackTrace) { - await MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); - log.error(e.toString()); - log.error('at PBPluginControlService'); - node = parentnode; - } - // print( - // 'Pre-Layout Service executed in ${stopwatch.elapsedMilliseconds} milliseconds.'); - stopwatch1.stop(); - return node; - } - - Future layoutGenerationService( - PBIntermediateNode parentNode, var context, var stopwatch2) async { - PBIntermediateNode node; - try { - node = PBLayoutGenerationService(currentContext: context) - .extractLayouts(parentNode); - } catch (e, stackTrace) { - await MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); - log.error(e.toString()); - log.error('at PBLayoutGenerationService'); - node = parentNode; - } - - node = await _pbPrototypeLinkerService.linkPrototypeNodes(node); - // print( - // 'Layout Generation Service executed in ${stopwatch.elapsedMilliseconds} milliseconds.'); - stopwatch2.stop(); - return node; - } - - Future alignGenerationService( - PBIntermediateNode parentnode, var context, var stopwatch3) async { - PBIntermediateNode node; - /// This covers a case where the designer created an empty group. This would cause an issue as there is nothing to align. - if (parentnode is TempGroupLayoutNode) { - return null; - } - - try { - node = PBAlignGenerationService(parentnode, currentContext: context) - .addAlignmentToLayouts(); - } catch (e, stackTrace) { - await MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); - log.error(e.toString()); - log.error('at PBAlignGenerationService'); - node = parentnode; - } - // print( - // 'Align Generation Service executed in ${stopwatch.elapsedMilliseconds} milliseconds.'); - stopwatch3.stop(); - return node; } -} diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 8868e934..af7bfb56 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -6,7 +6,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:uuid/uuid.dart'; ///Row contains nodes that are all `overlapping` to each other, without overlapping eachother diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 567d84df..ebf638f7 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -1,4 +1,3 @@ -import 'package:build/build.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; @@ -6,11 +5,40 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.da import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; -import 'package:path/path.dart'; class PBContext { final PBConfiguration configuration; - Point screenTopLeftCorner, screenBottomRightCorner; + + /// These are the original screen mesurements comming from the design values. + Point _screenTLC; + Point get screenTopLeftCorner => _screenTLC; + set screenTopLeftCorner(Point screenTopLeftCorner) { + if (_screenTLC == null) { + focusAreaTLC = screenTopLeftCorner; + } + _screenTLC = screenTopLeftCorner; + } + + Point _screenBRC; + Point get screenBottomRightCorner => _screenBRC; + set screenBottomRightCorner(Point screenBottomRightCorner) { + if (_screenBRC == null) { + focusAreaBRC = screenBottomRightCorner; + } + _screenBRC = screenBottomRightCorner; + } + + double get originalScreenWidth => Point.dist(_screenTLC, _screenBRC); + double get originaScreenHeight => Point.dist(_screenTLC, _screenBRC, true); + + /// These values represent the current "focus area" size as it travels down the + /// tree. + /// + /// The size of the canvas is changed by some widgets, for example, if there is an + /// appbar declared in the Scaffold, then the canvas should decrese in size to accomodate for that. + Point focusAreaTLC; + Point focusAreaBRC; + PBIntermediateTree tree; PBProject project; SizingValueContext sizingContext = SizingValueContext.PointValue; @@ -31,16 +59,14 @@ class PBContext { /// Getting the correct ratio measurement in respect to the original [screenTopLeftCorner] /// or the [screenBottomRightCorner] sizes. - /// - /// [isHorizontal] (default value is `false`) + /// + /// [isHorizontal] (default value is `false`) /// represents if the ratio should be the Horizontal one or the Vertical one. - double getRatioPercentage(double size, [bool isHorizontal = false]){ - if(size == 0){ + double getRatioPercentage(double size, [bool isHorizontal = false]) { + if (size == 0) { return size; } - var screenWidth = (screenBottomRightCorner.x - screenTopLeftCorner.x).abs(); - var screenHeight = (screenBottomRightCorner.y - screenTopLeftCorner.y).abs(); - return isHorizontal ? size / screenWidth : size / screenHeight; + return isHorizontal ? size / originalScreenWidth : size / originaScreenHeight; } } diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 8605e011..22959e6d 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -3,7 +3,12 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_state.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_variation.dart'; @@ -83,18 +88,18 @@ class PBStateManagementLinker { /// the necessary interpretation services. Future _interpretVariationNode( PBIntermediateNode node) async { - var visualServiceResult = await interpret.visualGenerationService( + var tree = PBIntermediateTree(node.name); + tree.rootNode = await interpret.visualGenerationService( (node as PBInheritedIntermediate).originalRef, node.currentContext, Stopwatch()..start(), ignoreStates: true); - var pluginServiceResult = await interpret.pluginService( - visualServiceResult, node.currentContext, Stopwatch()..start()); - var layoutServiceResult = await interpret.layoutGenerationService( - pluginServiceResult, - pluginServiceResult.currentContext, - Stopwatch()..start()); - return await interpret.alignGenerationService(layoutServiceResult, - layoutServiceResult.currentContext, Stopwatch()..start()); + var builder = AITServiceBuilder(node.currentContext, tree); + builder + .addTransformation( + PBPluginControlService().convertAndModifyPluginNodeTree) + .addTransformation(PBLayoutGenerationService().extractLayouts) + .addTransformation(PBAlignGenerationService().addAlignmentToLayouts); + return builder.build().then((tree) => tree.rootNode); } } diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index 9c740c0c..422b6847 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/layer_tuple.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:quick_log/quick_log.dart'; @@ -10,19 +11,18 @@ import 'package:quick_log/quick_log.dart'; /// Interpret the alignment relationship between a child node and a parent Visual or Layout Node. After interpretation, inject the proper alignment whether that’s Padding based or Flex-based. /// Input: PBIntermediateNode Tree /// Output: PBIntermediateNode Tree -class PBAlignGenerationService implements PBGenerationService { - /// The originalRoot intermediate node. - PBIntermediateNode originalRoot; - +class PBAlignGenerationService implements AITService { var log; /// Constructor for PBPluginGenerationService, must include the root SketchNode - PBAlignGenerationService(this.originalRoot, {this.currentContext}) { + PBAlignGenerationService() { log = Logger(runtimeType.toString()); } /// Should find all layout nodes - PBIntermediateNode addAlignmentToLayouts() { + Future addAlignmentToLayouts(PBIntermediateTree tree, PBContext context) { + currentContext = context; + var originalRoot = tree.rootNode; if (originalRoot == null) { log.warning( '[PBAlignmentGenerationService] generate() attempted to generate a non-existing tree'); @@ -51,7 +51,8 @@ class PBAlignGenerationService implements PBGenerationService { }); } } - return originalRoot; + tree.rootNode = originalRoot; + return Future.value(tree); } @override diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index e201703f..d8059054 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -13,17 +13,18 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; ///tree.where((element) => element != null).toList().reversed.map((e) => e.name).toList() -class PBConstraintGenerationService implements PBGenerationService { +class PBConstraintGenerationService implements AITService { @override PBContext currentContext; - PBConstraintGenerationService({this.currentContext}); + PBConstraintGenerationService(); /// Traverse to the bottom of the tree, and implement constraints to nodes that don't already contain it such as [InjectedContainer] and then work our way up the tree. /// Through Traversal, discover whether there are elements that will conflict on scaling, if so, change the layout to a Stack. - PBIntermediateTree implementConstraints(PBIntermediateTree tree) { + Future implementConstraints(PBIntermediateTree tree, PBContext context) { + currentContext = context; if (tree.rootNode == null) { - return tree; + return Future.value(tree); } for (var node @@ -74,7 +75,7 @@ class PBConstraintGenerationService implements PBGenerationService { } } } - return tree; + return Future.value(tree); } /// Go through children and find out if there's a node that will overlap another node when scaling. diff --git a/lib/interpret_and_optimize/services/pb_generation_service.dart b/lib/interpret_and_optimize/services/pb_generation_service.dart index 1cbb906a..2f7322e9 100644 --- a/lib/interpret_and_optimize/services/pb_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_generation_service.dart @@ -1,9 +1,71 @@ +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/design_logic/design_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:quick_log/quick_log.dart'; /// Abstract class for Generatiion Services /// so they all have the current context -abstract class PBGenerationService { +abstract class AITService { PBContext currentContext; - PBGenerationService({this.currentContext}); + AITService({this.currentContext}); +} + +typedef AITTransformation = Future Function( + PBIntermediateTree, PBContext); +typedef AITNodeTransformation = Future Function(PBIntermediateNode, PBContext); + +class AITServiceBuilder { + Logger log; + + PBIntermediateTree _intermediateTree; + set intermediateTree(PBIntermediateTree tree) => _intermediateTree = tree; + + final PBContext _context; + Stopwatch _stopwatch; + + /// These are the [AITService]s that are going to be transforming + /// the [_intermediateTree]. + final List _transformations; + + AITServiceBuilder(this._context, + [this._intermediateTree,this._transformations = const [],]) { + log = Logger(runtimeType.toString()); + _stopwatch = Stopwatch(); + } + + AITServiceBuilder addTransformation(AITTransformation transformation) { + if (transformation != null) { + _transformations.add(transformation); + } + return this; + } + + Future build() async { + for (var transformation in _transformations) { + var name = transformation.runtimeType.toString(); + _stopwatch.start(); + log.info('Started running $name...'); + try { + if(transformation is AITNodeTransformation){ + for(var node in _intermediateTree){ + node = await transformation(node, _context); + } + } + else{ + _intermediateTree = await transformation(_intermediateTree, _context); + } + } catch (e) { + MainInfo().captureException(e); + log.error( + '${e.toString()} at $name'); + } finally { + _stopwatch.stop(); + log.info('stoped running $name (${_stopwatch.elapsed.inSeconds} sec)'); + } + } + return _intermediateTree; + } } diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 0025e331..83063776 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -13,6 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:tuple/tuple.dart'; @@ -22,7 +23,7 @@ import 'package:uuid/uuid.dart'; /// Inject PBLayoutIntermediateNode to a PBIntermediateNode Tree that signifies the grouping of PBItermediateNodes in a given direction. There should not be any PBAlignmentIntermediateNode in the input tree. /// Input: PBVisualIntermediateNode Tree or PBLayoutIntermediate Tree /// Output:PBIntermediateNode Tree -class PBLayoutGenerationService implements PBGenerationService { +class PBLayoutGenerationService implements AITService { ///The available Layouts that could be injected. final List _availableLayouts = []; @@ -42,7 +43,7 @@ class PBLayoutGenerationService implements PBGenerationService { ///The default [PBLayoutIntermediateNode] PBLayoutIntermediateNode _defaultLayout; - PBLayoutGenerationService({this.currentContext}) { + PBLayoutGenerationService() { var layoutHandlers = { // 'column': PBIntermediateColumnLayout( // '', @@ -56,7 +57,7 @@ class PBLayoutGenerationService implements PBGenerationService { }; for (var layoutType - in currentContext.configuration.layoutPrecedence ?? ['column']) { + in MainInfo().configuration.layoutPrecedence ?? ['column']) { layoutType = layoutType.toLowerCase(); if (layoutHandlers.containsKey(layoutType)) { _availableLayouts.add(layoutHandlers[layoutType]); @@ -66,11 +67,13 @@ class PBLayoutGenerationService implements PBGenerationService { _defaultLayout = _availableLayouts[0]; } - PBIntermediateNode extractLayouts( - PBIntermediateNode rootNode, + Future extractLayouts( + PBIntermediateTree tree, PBContext context ) { + currentContext = context; + var rootNode = tree.rootNode; if (rootNode == null) { - return rootNode; + return Future.value(tree); } try { rootNode = _traverseLayersUtil(rootNode, (layer) { @@ -87,7 +90,7 @@ class PBLayoutGenerationService implements PBGenerationService { ///After all the layouts are generated, the [PostConditionRules] are going ///to be applyed to the layerss - return _applyPostConditionRules(rootNode); + _applyPostConditionRules(rootNode); } catch (e, stackTrace) { MainInfo().sentry.captureException( exception: e, @@ -95,7 +98,8 @@ class PBLayoutGenerationService implements PBGenerationService { ); log.error(e.toString()); } finally { - return rootNode; + tree.rootNode = rootNode; + return Future.value(tree); } } diff --git a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart index c0477d7e..b9bd5927 100644 --- a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart +++ b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/layer_tuple.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:quick_log/quick_log.dart'; @@ -11,18 +12,18 @@ import 'package:quick_log/quick_log.dart'; /// When finding a plugin node, we call layoutInstruction(). This gives the PluginNdoe the ability to modify the relevant tree if needed. /// Input: PBIntermediateTree /// Output: PBIntermediateTree -class PBPluginControlService implements PBGenerationService { - /// The originalRoot intermediate node. - PBIntermediateNode originalRoot; +class PBPluginControlService implements AITService { + var log = Logger('Plugin Control Service'); /// Constructor for PBPluginGenerationService, must include the root SketchNode - PBPluginControlService(this.originalRoot, {this.currentContext}); + PBPluginControlService(); /// Builds and returns intermediate tree by breadth depth first. /// @return Returns the root node of the intermediate tree. - PBIntermediateNode convertAndModifyPluginNodeTree() { + Future convertAndModifyPluginNodeTree(PBIntermediateTree tree, PBContext context) { + var originalRoot = tree.rootNode; if (originalRoot == null) { log.warning( '[PBPluginControlService] generate() attempted to generate a non-existing tree.'); @@ -79,7 +80,8 @@ class PBPluginControlService implements PBGenerationService { } } } - return rootIntermediateNode; + tree.rootNode = rootIntermediateNode; + return Future.value(tree); } @override diff --git a/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart b/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart index bcb5a51c..9c842ee3 100644 --- a/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_serv /// Input: SketchNode /// Output: PBIntermediateNode, null (No Semantics found that matches that SketchNode), or DenyListNode if the node is part of a DenyList set in the configuration. -class PBSemanticGenerationService implements PBGenerationService { +class PBSemanticGenerationService implements AITService { PBSemanticGenerationService({this.currentContext}); /// Return DenyListNode if found in the deny List. Return null if there were no semantic node found. Return any other type of PBIntermediateNode if we can tell from direct or indirect semantics. diff --git a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart index 3cf24849..f2e27449 100644 --- a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart @@ -18,7 +18,7 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_serv /// Takes a SketchNodeTree and begins generating PBNode interpretations. For each node, the node is going to pass through the PBSemanticInterpretationService which checks if the node should generate a specific PBIntermediateNode based on the semantics that it contains. /// Input: SketchNodeTree /// Output: PBIntermediateNodeTree -class PBVisualGenerationService implements PBGenerationService { +class PBVisualGenerationService implements AITService { /// The originalRoot sketch node. DesignNode originalRoot; From 808e7b73340e47c96fa84d04f5f47379c1bd679e Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sat, 17 Jul 2021 22:05:02 -0600 Subject: [PATCH 233/404] --- lib/controllers/interpret.dart | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 5f71907b..82f779ac 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -118,11 +118,7 @@ class Interpret { PBAlignGenerationService().addAlignmentToLayouts ]; - var builder = AITServiceBuilder(currentContext, intermediateTree, aitServices) - .addTransformation((tree, context) { - print(tree.hashCode); - return Future.value(tree); - }); + var builder = AITServiceBuilder(currentContext, intermediateTree, aitServices); return builder.build(); } From a5ca6f6d7bb2ce990dc7a3dbf955bdf0a077b307 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 18 Jul 2021 02:24:36 -0600 Subject: [PATCH 234/404] WIP integrated all services into the Builder pattern --- lib/controllers/interpret.dart | 145 ++++++++++++------ .../helpers/pb_state_management_linker.dart | 18 ++- .../pb_alignment_generation_service.dart | 8 +- .../pb_constraint_generation_service.dart | 8 +- .../services/pb_generation_service.dart | 68 ++------ .../pb_layout_generation_service.dart | 54 ++++--- .../services/pb_plugin_control_service.dart | 6 +- .../pb_semantic_generation_service.dart | 2 +- .../services/pb_symbol_linker_service.dart | 18 ++- .../pb_visual_generation_service.dart | 54 ++++--- 10 files changed, 210 insertions(+), 171 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 82f779ac..8b701531 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -1,10 +1,11 @@ import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; import 'package:parabeac_core/input/helper/design_project.dart'; import 'package:parabeac_core/input/helper/design_page.dart'; import 'package:parabeac_core/input/helper/design_screen.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -19,8 +20,6 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_s import 'package:parabeac_core/interpret_and_optimize/services/pb_visual_generation_service.dart'; import 'package:quick_log/quick_log.dart'; -import 'main_info.dart'; - class Interpret { var log = Logger('Interpret'); @@ -96,58 +95,116 @@ class Interpret { Future _generateScreen(DesignScreen designScreen) async { var currentContext = PBContext(configuration); - - var parentComponent = designScreen.designNode; - - var stopwatch = Stopwatch()..start(); - - /// VisualGenerationService - var intermediateTree = PBIntermediateTree(designScreen.designNode.name); - currentContext.tree = intermediateTree; currentContext.project = _pb_project; - intermediateTree.rootNode = await visualGenerationService( - parentComponent, currentContext, stopwatch); - if (intermediateTree.rootNode == null) { - return intermediateTree; - } var aitServices = [ - PBPluginControlService().convertAndModifyPluginNodeTree, - PBLayoutGenerationService().extractLayouts, - PBConstraintGenerationService().implementConstraints, - PBAlignGenerationService().addAlignmentToLayouts + PBVisualGenerationService().getIntermediateTree, + PBSymbolLinkerService(), + PBPluginControlService(), + PBLayoutGenerationService(), + PBConstraintGenerationService(), + PBAlignGenerationService() ]; - var builder = AITServiceBuilder(currentContext, intermediateTree, aitServices); + var builder = + AITServiceBuilder(currentContext, designScreen.designNode, aitServices); return builder.build(); + } +} + +class AITServiceBuilder { + Logger log; + + PBIntermediateTree _intermediateTree; + set intermediateTree(PBIntermediateTree tree) => _intermediateTree = tree; + + final PBContext _context; + Stopwatch _stopwatch; + + /// These are the [AITHandler]s that are going to be transforming + /// the [_intermediateTree]. + final List _transformations = []; + + final DesignNode designNode; + + AITServiceBuilder(this._context, this.designNode, [List transformations]) { + log = Logger(runtimeType.toString()); + _stopwatch = Stopwatch(); + + if (transformations != null) { + transformations.forEach(addTransformation); + if (_verifyTransformationsFailed()) { + throw Error(); + } + } + } + + AITServiceBuilder addTransformation(transformation) { + if (transformation is AITHandler) { + _transformations.add(transformation.handleTree); + } else if (transformation is AITNodeTransformation || transformation is PBDLConversion) { + _transformations.add(transformation); + } + return this; + } + /// Verifies that only the allows data types are within the [_transformations] + bool _verifyTransformationsFailed() { + return _transformations.any((transformation) => + transformation is! AITHandler && + transformation is! AITNodeTransformation && + transformation is! PBDLConversion && + transformation is! AITTransformation); } - // TODO: refactor this method and/or `getIntermediateTree` - // to not take the [ignoreStates] variable. - Future visualGenerationService( - var component, var context, var stopwatch, - {bool ignoreStates = false}) async { - /// VisualGenerationService - PBIntermediateNode node; + Future _pbdlConversion(PBDLConversion conversion) async { try { - node = await PBVisualGenerationService(component, - currentContext: context, ignoreStates: ignoreStates) - .getIntermediateTree(); - } catch (e, stackTrace) { - await MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); - log.error(e.toString()); - log.error('at PBVisualGenerationService'); + _stopwatch.start(); + log.fine('Converting ${designNode.name} to AIT'); + _intermediateTree = await conversion(designNode, _context); + _context.tree = _intermediateTree; + _stopwatch.stop(); + log.fine( + 'Finished with ${designNode.name} (${_stopwatch.elapsedMilliseconds}'); + return _intermediateTree; + } catch (e) { + MainInfo().captureException(e); + log.error('PBDL Conversion was not possible'); + + /// Exit from Parabeac-Core + throw Error(); } - // print( - // 'Visual Generation Service executed in ${stopwatch.elapsedMilliseconds} milliseconds.'); - stopwatch.stop(); - node = await _pbSymbolLinkerService.linkSymbols(node); - return node; } - + Future build() async { + var pbdlConversion = _transformations + .firstWhere((transformation) => transformation is PBDLConversion); + if (pbdlConversion == null) { + throw Error(); + } + _transformations.removeWhere((element) => element is PBDLConversion); + await _pbdlConversion(pbdlConversion); + + for (var transformation in _transformations) { + var name = transformation.toString(); + _stopwatch.start(); + log.fine('Started running $name...'); + try { + if (transformation is AITNodeTransformation) { + for (var node in _intermediateTree) { + node = await transformation(_context, node); + } + } else if (transformation is AITTransformation) { + _intermediateTree = await transformation(_context, _intermediateTree); + } + } catch (e) { + MainInfo().captureException(e); + log.error('${e.toString()} at $name'); + } finally { + _stopwatch.stop(); + log.fine('stoped running $name (${_stopwatch.elapsed.inMilliseconds})'); + } + } + return _intermediateTree; } +} diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 22959e6d..0e50da57 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_gener import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_visual_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_state.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_variation.dart'; @@ -88,14 +89,17 @@ class PBStateManagementLinker { /// the necessary interpretation services. Future _interpretVariationNode( PBIntermediateNode node) async { - var tree = PBIntermediateTree(node.name); - tree.rootNode = await interpret.visualGenerationService( - (node as PBInheritedIntermediate).originalRef, - node.currentContext, - Stopwatch()..start(), - ignoreStates: true); - var builder = AITServiceBuilder(node.currentContext, tree); + var visualGenerationService = PBVisualGenerationService(); + visualGenerationService.ignoreStates = true; + + var builder = AITServiceBuilder( + node.currentContext, (node as PBInheritedIntermediate).originalRef); builder + .addTransformation(visualGenerationService.getIntermediateTree) + .addTransformation((PBIntermediateTree tree, context) { + /// Making sure the name of the tree was changed back + tree.name = node.name; + }) .addTransformation( PBPluginControlService().convertAndModifyPluginNodeTree) .addTransformation(PBLayoutGenerationService().extractLayouts) diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index 422b6847..b6f37ee2 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -1,4 +1,3 @@ -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/layer_tuple.dart'; @@ -11,7 +10,7 @@ import 'package:quick_log/quick_log.dart'; /// Interpret the alignment relationship between a child node and a parent Visual or Layout Node. After interpretation, inject the proper alignment whether that’s Padding based or Flex-based. /// Input: PBIntermediateNode Tree /// Output: PBIntermediateNode Tree -class PBAlignGenerationService implements AITService { +class PBAlignGenerationService implements AITHandler { var log; /// Constructor for PBPluginGenerationService, must include the root SketchNode @@ -57,4 +56,9 @@ class PBAlignGenerationService implements AITService { @override PBContext currentContext; + + @override + Future handleTree(PBContext context, PBIntermediateTree tree) { + return addAlignmentToLayouts(tree, context); + } } diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index d8059054..c3c2b191 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -13,7 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; ///tree.where((element) => element != null).toList().reversed.map((e) => e.name).toList() -class PBConstraintGenerationService implements AITService { +class PBConstraintGenerationService implements AITHandler { @override PBContext currentContext; @@ -189,4 +189,10 @@ class PBConstraintGenerationService implements AITService { } return constraints; } + + @override + Future handleTree(PBContext context, PBIntermediateTree tree) { + return implementConstraints(tree, context); + + } } diff --git a/lib/interpret_and_optimize/services/pb_generation_service.dart b/lib/interpret_and_optimize/services/pb_generation_service.dart index 2f7322e9..3d9d7d9a 100644 --- a/lib/interpret_and_optimize/services/pb_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_generation_service.dart @@ -1,71 +1,23 @@ -import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:quick_log/quick_log.dart'; /// Abstract class for Generatiion Services /// so they all have the current context -abstract class AITService { - PBContext currentContext; - - AITService({this.currentContext}); +abstract class AITHandler { + /// Delegates the tranformation/modification to the current [AITHandler] + Future handleTree( + PBContext context, PBIntermediateTree tree); + AITHandler(); } typedef AITTransformation = Future Function( - PBIntermediateTree, PBContext); -typedef AITNodeTransformation = Future Function(PBIntermediateNode, PBContext); - -class AITServiceBuilder { - Logger log; - - PBIntermediateTree _intermediateTree; - set intermediateTree(PBIntermediateTree tree) => _intermediateTree = tree; + PBContext, PBIntermediateTree); +typedef AITNodeTransformation = Future Function( + PBContext, PBIntermediateNode); - final PBContext _context; - Stopwatch _stopwatch; +typedef PBDLConversion = Future Function( + DesignNode, PBContext); - /// These are the [AITService]s that are going to be transforming - /// the [_intermediateTree]. - final List _transformations; - AITServiceBuilder(this._context, - [this._intermediateTree,this._transformations = const [],]) { - log = Logger(runtimeType.toString()); - _stopwatch = Stopwatch(); - } - - AITServiceBuilder addTransformation(AITTransformation transformation) { - if (transformation != null) { - _transformations.add(transformation); - } - return this; - } - - Future build() async { - for (var transformation in _transformations) { - var name = transformation.runtimeType.toString(); - _stopwatch.start(); - log.info('Started running $name...'); - try { - if(transformation is AITNodeTransformation){ - for(var node in _intermediateTree){ - node = await transformation(node, _context); - } - } - else{ - _intermediateTree = await transformation(_intermediateTree, _context); - } - } catch (e) { - MainInfo().captureException(e); - log.error( - '${e.toString()} at $name'); - } finally { - _stopwatch.stop(); - log.info('stoped running $name (${_stopwatch.elapsed.inSeconds} sec)'); - } - } - return _intermediateTree; - } -} diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 83063776..29b50913 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -1,9 +1,6 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/container_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; @@ -23,7 +20,7 @@ import 'package:uuid/uuid.dart'; /// Inject PBLayoutIntermediateNode to a PBIntermediateNode Tree that signifies the grouping of PBItermediateNodes in a given direction. There should not be any PBAlignmentIntermediateNode in the input tree. /// Input: PBVisualIntermediateNode Tree or PBLayoutIntermediate Tree /// Output:PBIntermediateNode Tree -class PBLayoutGenerationService implements AITService { +class PBLayoutGenerationService implements AITHandler { ///The available Layouts that could be injected. final List _availableLayouts = []; @@ -36,9 +33,6 @@ class PBLayoutGenerationService implements AITService { ContainerConstraintRule() ]; - @override - PBContext currentContext; - ///Going to replace the [TempGroupLayoutNode]s by [PBLayoutIntermediateNode]s ///The default [PBLayoutIntermediateNode] PBLayoutIntermediateNode _defaultLayout; @@ -52,8 +46,10 @@ class PBLayoutGenerationService implements AITService { // ), // 'row': PBIntermediateRowLayout('', Uuid().v4(), // currentContext: currentContext), - 'stack': PBIntermediateStackLayout('', Uuid().v4(), - currentContext: currentContext), + 'stack': PBIntermediateStackLayout( + '', + Uuid().v4(), + ), }; for (var layoutType @@ -68,20 +64,24 @@ class PBLayoutGenerationService implements AITService { } Future extractLayouts( - PBIntermediateTree tree, PBContext context - ) { - currentContext = context; + PBIntermediateTree tree, PBContext context) { var rootNode = tree.rootNode; if (rootNode == null) { return Future.value(tree); } try { + // rootNode = (tree + // .map(_removingMeaninglessGroup) + // .map((node) => _layoutConditionalReplacement(node, context)) + // .toList() + // ..removeWhere((element) => element == null)) + // .first; rootNode = _traverseLayersUtil(rootNode, (layer) { return layer ///Remove the `TempGroupLayout` nodes that only contain one node .map(_removingMeaninglessGroup) - .map(_layoutConditionalReplacement) + .map((node) => _layoutConditionalReplacement(node, context)) .toList() /// Filter out the elements that are null in the tree @@ -91,6 +91,7 @@ class PBLayoutGenerationService implements AITService { ///After all the layouts are generated, the [PostConditionRules] are going ///to be applyed to the layerss _applyPostConditionRules(rootNode); + // return Future.value(tree); } catch (e, stackTrace) { MainInfo().sentry.captureException( exception: e, @@ -171,7 +172,8 @@ class PBLayoutGenerationService implements AITService { ///nodes should be considered into subsections. For example, if child 0 and child 1 statisfy the ///rule of a [Row] but not child 3, then child 0 and child 1 should be placed inside of a [Row]. Therefore, ///there could be many[IntermediateLayoutNodes] derived in the children level of the `group`. - PBIntermediateNode _layoutConditionalReplacement(PBIntermediateNode parent, + PBIntermediateNode _layoutConditionalReplacement( + PBIntermediateNode parent, PBContext context, {depth = 1}) { if (parent is PBLayoutIntermediateNode && depth >= 0) { parent.sortChildren(); @@ -192,21 +194,21 @@ class PBLayoutGenerationService implements AITService { ///then its going to use either one instead of creating a new [PBLayoutIntermediateNode]. if (layout.runtimeType == currentNode.runtimeType) { currentNode.addChild(nextNode); - currentNode = - _layoutConditionalReplacement(currentNode, depth: depth - 1); + currentNode = _layoutConditionalReplacement(currentNode, context, + depth: depth - 1); generatedLayout = currentNode; } else if (layout.runtimeType == nextNode.runtimeType) { nextNode.addChild(currentNode); - nextNode = - _layoutConditionalReplacement(nextNode, depth: depth - 1); + nextNode = _layoutConditionalReplacement(nextNode, context, + depth: depth - 1); generatedLayout = nextNode; } ///If neither of the current nodes are of the same `runtimeType` as the layout, we are going to use the actual ///satified [PBLayoutIntermediateNode] to generate the layout. We place both of the nodes inside ///of the generated layout. - generatedLayout ??= layout - .generateLayout([currentNode, nextNode], currentContext, ''); + generatedLayout ??= + layout.generateLayout([currentNode, nextNode], context, ''); var start = childPointer, end = childPointer + 2; children.replaceRange( start, @@ -230,10 +232,8 @@ class PBLayoutGenerationService implements AITService { } else { return parent is! TempGroupLayoutNode ? parent - : _replaceNode( - parent, - _defaultLayout.generateLayout( - children, currentContext, parent.name)); + : _replaceNode(parent, + _defaultLayout.generateLayout(children, context, parent.name)); } } return parent; @@ -271,4 +271,10 @@ class PBLayoutGenerationService implements AITService { } return node; } + + @override + Future handleTree( + PBContext context, PBIntermediateTree tree) { + return extractLayouts(tree, context); + } } diff --git a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart index b9bd5927..9aa810d4 100644 --- a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart +++ b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart @@ -12,7 +12,7 @@ import 'package:quick_log/quick_log.dart'; /// When finding a plugin node, we call layoutInstruction(). This gives the PluginNdoe the ability to modify the relevant tree if needed. /// Input: PBIntermediateTree /// Output: PBIntermediateTree -class PBPluginControlService implements AITService { +class PBPluginControlService implements AITHandler { var log = Logger('Plugin Control Service'); @@ -85,5 +85,7 @@ class PBPluginControlService implements AITService { } @override - PBContext currentContext; + Future handleTree(PBContext context, PBIntermediateTree tree) { + return convertAndModifyPluginNodeTree(tree, context); + } } diff --git a/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart b/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart index 9c842ee3..08431075 100644 --- a/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_serv /// Input: SketchNode /// Output: PBIntermediateNode, null (No Semantics found that matches that SketchNode), or DenyListNode if the node is part of a DenyList set in the configuration. -class PBSemanticGenerationService implements AITService { +class PBSemanticGenerationService { PBSemanticGenerationService({this.currentContext}); /// Return DenyListNode if found in the deny List. Return null if there were no semantic node found. Return any other type of PBIntermediateNode if we can tell from direct or indirect semantics. diff --git a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart index 2adee0ca..3b30916d 100644 --- a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart @@ -3,10 +3,13 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_n import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_shared_aggregation_service.dart'; -class PBSymbolLinkerService { +class PBSymbolLinkerService implements AITHandler{ PBSymbolStorage _symbolStorage; PBSharedInterAggregationService _aggregationService; @@ -17,9 +20,10 @@ class PBSymbolLinkerService { // /Linking [PBSharedMasterNode] and [PBSharedInstanceIntermediateNode] together; linking its // /parameter and values. - Future linkSymbols(PBIntermediateNode rootNode) async{ + Future linkSymbols(PBIntermediateTree tree) async{ + var rootNode = tree.rootNode; if(rootNode == null){ - return rootNode; + return Future.value(tree); } var stack = []; @@ -45,6 +49,12 @@ class PBSymbolLinkerService { rootIntermediateNode ??= currentNode; } - return rootIntermediateNode; + tree.rootNode = rootIntermediateNode; + return Future.value(tree); + } + + @override + Future handleTree(PBContext context, PBIntermediateTree tree) { + return linkSymbols(tree); } } diff --git a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart index f2e27449..9985d2bd 100644 --- a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart @@ -11,51 +11,46 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/node_tuple.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_deny_list_helper.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; /// Takes a SketchNodeTree and begins generating PBNode interpretations. For each node, the node is going to pass through the PBSemanticInterpretationService which checks if the node should generate a specific PBIntermediateNode based on the semantics that it contains. /// Input: SketchNodeTree /// Output: PBIntermediateNodeTree -class PBVisualGenerationService implements AITService { - /// The originalRoot sketch node. - DesignNode originalRoot; +class PBVisualGenerationService{ PositionalCleansingService _positionalCleansingService; - @override - PBContext currentContext; - PBStateManagementHelper smHelper; /// Boolean that is `true` if the [VisualGenerationService] /// is currently processing a state management node - bool _ignoreStates; + bool ignoreStates = false; - /// Constructor for PBVisualGenerationService, must include the root SketchNode - PBVisualGenerationService(originalRoot, - {this.currentContext, bool ignoreStates = false}) { - _ignoreStates = ignoreStates; + PBVisualGenerationService() { + _positionalCleansingService = PositionalCleansingService(); + smHelper = PBStateManagementHelper(); + } + + DesignNode _positionalOffsetAdjustment(DesignNode designNode){ // Only do positional cleansing for non-state nodes, since those nodes // have already been through this service - if (!_ignoreStates) { - _positionalCleansingService = PositionalCleansingService(); - this.originalRoot = - _positionalCleansingService.eliminateOffset(originalRoot); - } else { - this.originalRoot = originalRoot; + if(designNode != null && !ignoreStates){ + return _positionalCleansingService.eliminateOffset(designNode); } - - smHelper = PBStateManagementHelper(); + return designNode; } /// Builds and returns intermediate tree by breadth depth first. /// @return Returns the root node of the intermediate tree. - Future getIntermediateTree() async { + Future getIntermediateTree(DesignNode originalRoot, PBContext currentContext) async { if (originalRoot == null) { return Future.value(null); } + var tree = PBIntermediateTree(originalRoot.name); + originalRoot = _positionalOffsetAdjustment(originalRoot); + PBPluginListHelper().initPlugins(currentContext); var queue = []; @@ -85,7 +80,7 @@ class PBVisualGenerationService implements AITService { } // Interpret state management node - if (!_ignoreStates && + if (!ignoreStates && smHelper.isValidStateNode(result.name) && (currentNode.designNode.name != currentNode.convertedParent?.name ?? @@ -105,6 +100,10 @@ class PBVisualGenerationService implements AITService { // If we haven't assigned the rootIntermediateNode, this must be the first node, aka root node. rootIntermediateNode ??= result; + if(rootIntermediateNode != null){ + _extractScreenSize(rootIntermediateNode, currentContext); + } + if (result != null) { // Add next depth to queue. @@ -130,19 +129,18 @@ class PBVisualGenerationService implements AITService { prototypeNode, rootIntermediateNode.currentContext); destHolder.addChild(rootIntermediateNode); - return destHolder; - } - if (rootIntermediateNode != null) { - _extractScreenSize(rootIntermediateNode); + tree.rootNode = destHolder; + return Future.value(tree); } - return rootIntermediateNode; + tree.rootNode = rootIntermediateNode; + return Future.value(tree); } ///Sets the size of the UI element. /// ///We are assuming that since the [rootIntermediateNode] contains all of the nodes ///then it should represent the biggest screen size that encapsulates the entire UI elements. - void _extractScreenSize(PBIntermediateNode rootIntermediateNode) { + void _extractScreenSize(PBIntermediateNode rootIntermediateNode, PBContext currentContext) { if ((currentContext.screenBottomRightCorner == null && currentContext.screenTopLeftCorner == null) || (currentContext.screenBottomRightCorner != From bb10399abdc0a7b7eee07fb0aebf76bb0c1f357b Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 18 Jul 2021 12:15:53 -0600 Subject: [PATCH 235/404] REFACTORED traversal on align service to leverage the traversal method on intermediate tree --- .../pb_alignment_generation_service.dart | 35 +++++-------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index b6f37ee2..83bf8c47 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -1,6 +1,5 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/layer_tuple.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; @@ -20,7 +19,6 @@ class PBAlignGenerationService implements AITHandler { /// Should find all layout nodes Future addAlignmentToLayouts(PBIntermediateTree tree, PBContext context) { - currentContext = context; var originalRoot = tree.rootNode; if (originalRoot == null) { log.warning( @@ -28,35 +26,18 @@ class PBAlignGenerationService implements AITHandler { return null; } - var queue = []; - queue.add(LayerTuple([originalRoot], null)); - while (queue.isNotEmpty) { - var currentLayer = queue.removeAt(0); - - for (var currentIntermediateNode in currentLayer.nodeLayer) { - if (currentIntermediateNode is PBVisualIntermediateNode) { - currentIntermediateNode.alignChild(); - } else if (currentIntermediateNode is PBLayoutIntermediateNode) { - currentIntermediateNode.alignChildren(); - } - if (currentIntermediateNode == null) { - continue; - } - - currentIntermediateNode.attributes.forEach((attribute) { - attribute.attributeNodes.forEach((node) { - queue.add(LayerTuple([node], currentIntermediateNode)); - }); - }); + tree.forEach((node) { + if(node is PBVisualIntermediateNode){ + node.alignChild(); } - } - tree.rootNode = originalRoot; + if(node is PBLayoutIntermediateNode){ + // TODO: convert to using aling() on each node. + node.alignChildren(); + } + }); return Future.value(tree); } - @override - PBContext currentContext; - @override Future handleTree(PBContext context, PBIntermediateTree tree) { return addAlignmentToLayouts(tree, context); From 5ea2284a80ff91c6de1c7fd440b79a7fc9570435 Mon Sep 17 00:00:00 2001 From: Evan Reyes Date: Mon, 19 Jul 2021 15:49:18 -0600 Subject: [PATCH 236/404] add customEggs skeleton --- lib/eggs/custom_egg.dart | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 lib/eggs/custom_egg.dart diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart new file mode 100644 index 00000000..50ca2b1e --- /dev/null +++ b/lib/eggs/custom_egg.dart @@ -0,0 +1,49 @@ +import 'package:parabeac_core/design_logic/design_node.dart'; +import 'package:parabeac_core/generation/generators/pb_generator.dart'; +import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; + +class CustomEgg extends PBEgg implements PBInjectedIntermediate{ + @override + String semanticName = ''; + CustomEgg(Point topLeftCorner, Point bottomRightCorner, PBContext currentContext, String name) : super(topLeftCorner, bottomRightCorner, currentContext, name) { + addAttribute(PBAttribute('child')); + generator = CustomEggGenerator(); + + } + + @override + void addChild(PBIntermediateNode node) { + // TODO: implement addChild + } + + @override + void alignChild() { + // TODO: implement alignChild + } + + @override + void extractInformation(DesignNode incomingNode) { + // TODO: implement extractInformation + } + + @override + PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef) { + // TODO: implement generatePluginNode + throw UnimplementedError(); + } + +} + +class CustomEggGenerator extends PBGenerator{ + @override + String generate(PBIntermediateNode source, PBContext context) { + // TODO: implement generate + throw UnimplementedError(); + } + +} \ No newline at end of file From 2fc6411dc5612224b6f7e7f1b3f70b1caa83eada Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Mon, 19 Jul 2021 17:52:47 -0600 Subject: [PATCH 237/404] WIP fixed a couple of small errors --- lib/controllers/interpret.dart | 1 - .../visual-widgets/pb_positioned_gen.dart | 10 +++++----- .../entities/inherited_scaffold.dart | 15 ++++++--------- .../helpers/pb_context.dart | 4 ++-- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 8b701531..1e65f7f0 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -5,7 +5,6 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service import 'package:parabeac_core/input/helper/design_project.dart'; import 'package:parabeac_core/input/helper/design_page.dart'; import 'package:parabeac_core/input/helper/design_screen.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index d1ac4d95..0cc766cf 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -26,13 +26,13 @@ class PBPositionedGenerator extends PBGenerator { ); valueHolder.left = - source.currentContext.getRatioPercentage(source.valueHolder.left); + source.currentContext.getRatioPercentage(source.valueHolder.left, true); valueHolder.right = - source.currentContext.getRatioPercentage(source.valueHolder.right); + source.currentContext.getRatioPercentage(source.valueHolder.right, true); valueHolder.top = source.currentContext - .getRatioPercentage(source.valueHolder.top, false); + .getRatioPercentage(source.valueHolder.top); valueHolder.bottom = source.currentContext - .getRatioPercentage(source.valueHolder.bottom, false); + .getRatioPercentage(source.valueHolder.bottom); if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { multStringH = 'MediaQuery.of(context).size.width * '; @@ -46,7 +46,7 @@ class PBPositionedGenerator extends PBGenerator { buffer.write( 'left: ${_normalizeValue(multStringH, valueHolder.left)}, right: ${_normalizeValue(multStringH, valueHolder.right)},'); buffer.write( - 'top: ${_normalizeValue(multStringH, valueHolder.top)}, bottom: ${_normalizeValue(multStringH, valueHolder.bottom)},'); + 'top: ${_normalizeValue(multStringV, valueHolder.top)}, bottom: ${_normalizeValue(multStringV, valueHolder.bottom)},'); try { source.child.currentContext = source.currentContext; diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 11844df9..444daa73 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -17,10 +17,8 @@ import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'interfaces/pb_inherited_intermediate.dart'; class InheritedScaffold extends PBVisualIntermediateNode - with - PBColorMixin - implements - /* with GeneratePBTree */ /* PropertySearchable,*/ PBInheritedIntermediate { + with PBColorMixin + implements PBInheritedIntermediate { @override var originalRef; @override @@ -89,8 +87,8 @@ class InheritedScaffold extends PBVisualIntermediateNode if (node is PBSharedInstanceIntermediateNode) { if (node.originalRef.name.contains('')) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); - // currentContext.canvasTLC = Point(currentContext.canvasTLC.x, - // currentContext.canvasTLC.y - node.topLeftCorner.y); + // currentContext.focusAreaTLC = Point(currentContext.focusAreaTLC.x, + // currentContext.focusAreaBRC.y - node.topLeftCorner.y); return; } if (node.originalRef.name.contains('')) { @@ -102,8 +100,8 @@ class InheritedScaffold extends PBVisualIntermediateNode if (node is InjectedAppbar) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); - // currentContext.canvasTLC = Point(currentContext.canvasTLC.x, - // currentContext.canvasTLC.y - node.topLeftCorner.y); + // currentContext.focusAreaBRC = Point(currentContext.focusAreaTLC.x, + // currentContext.focusAreaBRC.y - node.topLeftCorner.y); return; } if (node is InjectedTabBar) { @@ -132,7 +130,6 @@ class InheritedScaffold extends PBVisualIntermediateNode @override void alignChild() { if (child != null) { - var padding = Padding('', child.constraints, left: (child.topLeftCorner.x - topLeftCorner.x).abs(), right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index ebf638f7..dc7fb30b 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -29,7 +29,7 @@ class PBContext { } double get originalScreenWidth => Point.dist(_screenTLC, _screenBRC); - double get originaScreenHeight => Point.dist(_screenTLC, _screenBRC, true); + double get originaScreenHeight => Point.dist(_screenTLC, _screenBRC, false); /// These values represent the current "focus area" size as it travels down the /// tree. @@ -67,7 +67,7 @@ class PBContext { return size; } return isHorizontal ? size / originalScreenWidth : size / originaScreenHeight; - } + } } enum SizingValueContext { From aa5fd8300cef787dd1c5f7d9cc9d0632d6051b7a Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 20 Jul 2021 15:13:42 -0600 Subject: [PATCH 238/404] Added custom egg --- .../helpers/pb_plugin_list_helper.dart | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index d861c1fe..efb85e54 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/eggs/custom_egg.dart'; import 'package:parabeac_core/eggs/injected_app_bar.dart'; import 'package:parabeac_core/eggs/injected_tab.dart'; import 'package:parabeac_core/eggs/injected_tab_bar.dart'; @@ -19,6 +20,7 @@ class PBPluginListHelper { currentContext: context), '': Tab(Point(0, 0), Point(0, 0), '', currentContext: context, UUID: Uuid().v4()), + '': CustomEgg(Point(0, 0), Point(0, 0), ''), }; } @@ -34,9 +36,16 @@ class PBPluginListHelper { '', '', '', + '', ]; - List baseNames = ['', '', '', '']; + List baseNames = [ + '', + '', + '', + '', + '', + ]; /// Adds `node` to the list of plugin nodes if the semantic /// name does not exist From b1745fa7e34c3e84d6177f68bee101f4ca83346a Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 20 Jul 2021 15:13:58 -0600 Subject: [PATCH 239/404] Added generator and boilerplate --- lib/eggs/custom_egg.dart | 57 +++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 50ca2b1e..8e8faaf8 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -1,19 +1,25 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:uuid/uuid.dart'; -class CustomEgg extends PBEgg implements PBInjectedIntermediate{ +class CustomEgg extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; - CustomEgg(Point topLeftCorner, Point bottomRightCorner, PBContext currentContext, String name) : super(topLeftCorner, bottomRightCorner, currentContext, name) { + CustomEgg( + Point topLeftCorner, + Point bottomRightCorner, + String name, { + PBContext currentContext, + }) : super(topLeftCorner, bottomRightCorner, currentContext, name) { addAttribute(PBAttribute('child')); generator = CustomEggGenerator(); - } @override @@ -32,18 +38,51 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate{ } @override - PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef) { + PBEgg generatePluginNode( + Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef) { // TODO: implement generatePluginNode throw UnimplementedError(); } - } -class CustomEggGenerator extends PBGenerator{ +class CustomEggGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext context) { - // TODO: implement generate - throw UnimplementedError(); + // TODO: check if [source.name] it is actually formated as class name + context.configuration.generationConfiguration.fileStructureStrategy + .commandCreated(WriteSymbolCommand( + Uuid().v4(), + source.name, + customBoilerPlate(source.name), + relativePath: 'egg', + symbolPath: 'lib', + )); + if (source is CustomEgg) { + return ''' + ${source.name}( + child: ${source.attributes[0].attributeNode.generator.generate(source.attributes[0].attributeNode, context)} + ) + '''; + } + return ''; } +} -} \ No newline at end of file +String customBoilerPlate(String className) { + return ''' + class $className extends StatefullWidget{ + final Widget child; + $className({Key key, this.child}) : super (key: key); + + @override + _${className}State createState() => _${className}State(); + } + + class _${className}State extends State<$className> { + @override + Widget build(BuildContext context){ + return widget.child; + } + } + '''; +} From 63bd85d39cef874a5a0874c528eb7a4b88ff1461 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 20 Jul 2021 15:44:17 -0600 Subject: [PATCH 240/404] Implamented custom egg class --- lib/eggs/custom_egg.dart | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 8e8faaf8..84b6944e 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -1,13 +1,16 @@ import 'package:parabeac_core/design_logic/design_node.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:uuid/uuid.dart'; +import 'package:recase/recase.dart'; class CustomEgg extends PBEgg implements PBInjectedIntermediate { @override @@ -24,12 +27,19 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { @override void addChild(PBIntermediateNode node) { - // TODO: implement addChild + getAttributeNamed('child').attributeNode = node; } @override void alignChild() { - // TODO: implement alignChild + var tempNode = InjectedContainer( + child.bottomRightCorner, + child.topLeftCorner, + child.name, + child.UUID, + )..addChild(child); + + getAttributeNamed('title').attributeNode = tempNode; } @override @@ -40,19 +50,20 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode( Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef) { - // TODO: implement generatePluginNode - throw UnimplementedError(); + return CustomEgg(topLeftCorner, bottomRightCorner, + originalRef.name.replaceAll('', '').pascalCase); } } class CustomEggGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext context) { - // TODO: check if [source.name] it is actually formated as class name - context.configuration.generationConfiguration.fileStructureStrategy + // TODO: Do correct import + source.currentContext.configuration.generationConfiguration + .fileStructureStrategy .commandCreated(WriteSymbolCommand( Uuid().v4(), - source.name, + source.name.snakeCase, customBoilerPlate(source.name), relativePath: 'egg', symbolPath: 'lib', @@ -70,7 +81,9 @@ class CustomEggGenerator extends PBGenerator { String customBoilerPlate(String className) { return ''' - class $className extends StatefullWidget{ + import 'package:flutter/material.dart'; + + class $className extends StatefulWidget{ final Widget child; $className({Key key, this.child}) : super (key: key); From e4e5958453b8cf2e559cb6ea4b8b914fcdf20e32 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 20 Jul 2021 17:27:31 -0600 Subject: [PATCH 241/404] Added dynamic import --- lib/eggs/custom_egg.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 84b6944e..7beb4b5c 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; @@ -58,7 +59,11 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { class CustomEggGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext context) { - // TODO: Do correct import + // TODO: correct import + source.managerData.addImport(FlutterImport( + 'egg/${source.name.snakeCase}.dart', + MainInfo().projectName, + )); source.currentContext.configuration.generationConfiguration .fileStructureStrategy .commandCreated(WriteSymbolCommand( From 7ca1a7227dd40a9dc30f047cd8f1c904b666cc0a Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 20 Jul 2021 20:53:56 -0600 Subject: [PATCH 242/404] WIP changed the name of the canvas, fixed dependencies, and deleted irrelevant file. --- .../generators/plugins/pb_injected_node.dart | 14 -------------- lib/interpret_and_optimize/helpers/pb_context.dart | 11 +++++++---- pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 19 deletions(-) delete mode 100644 lib/generation/generators/plugins/pb_injected_node.dart diff --git a/lib/generation/generators/plugins/pb_injected_node.dart b/lib/generation/generators/plugins/pb_injected_node.dart deleted file mode 100644 index 18cf1e19..00000000 --- a/lib/generation/generators/plugins/pb_injected_node.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; - -class PBInjectedNode extends PBIntermediateNode { - PBInjectedNode( - Point topLeftCorner, - Point bottomRightCorner, - String UUID, - ) : super(topLeftCorner, bottomRightCorner, UUID, ''); - @override - void addChild(PBIntermediateNode node) { - // TODO: implement addChild - } -} diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index dc7fb30b..750c9484 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -14,7 +14,7 @@ class PBContext { Point get screenTopLeftCorner => _screenTLC; set screenTopLeftCorner(Point screenTopLeftCorner) { if (_screenTLC == null) { - focusAreaTLC = screenTopLeftCorner; + canvasTLC = screenTopLeftCorner; } _screenTLC = screenTopLeftCorner; } @@ -23,7 +23,7 @@ class PBContext { Point get screenBottomRightCorner => _screenBRC; set screenBottomRightCorner(Point screenBottomRightCorner) { if (_screenBRC == null) { - focusAreaBRC = screenBottomRightCorner; + canvasBRC = screenBottomRightCorner; } _screenBRC = screenBottomRightCorner; } @@ -36,8 +36,11 @@ class PBContext { /// /// The size of the canvas is changed by some widgets, for example, if there is an /// appbar declared in the Scaffold, then the canvas should decrese in size to accomodate for that. - Point focusAreaTLC; - Point focusAreaBRC; + /// Some of the scenarios the focusAreaWould change: + /// - When the appbar is used, it should shrink the canvas top point to make room for the appbar + /// - When another stack is declared, its TLC becomes the new canvas TLC(same for BRC). + Point canvasTLC; + Point canvasBRC; PBIntermediateTree tree; PBProject project; diff --git a/pubspec.yaml b/pubspec.yaml index 26aebba5..5ec63de9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: logger: ^0.8.3 uuid: ^2.1.0 quick_log: ^1.1.3 - sentry: ^5.1.0 + sentry: ^3.0.0 http2: ^1.0.1 recase: "^3.0.0" tuple: ^1.0.3 From 413f833168a18ff871e129246620e4647e47f1db Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 20 Jul 2021 20:57:30 -0600 Subject: [PATCH 243/404] Refactored and aggregated the different ways of adding an node. Many of the logic was being repeated across multiple class, therefore, I used strategy pattern to abstrack the logic of adding child to another node --- lib/controllers/interpret.dart | 9 +- lib/eggs/injected_app_bar.dart | 8 +- lib/eggs/injected_back_arrow.dart | 6 +- lib/eggs/injected_tab.dart | 9 +- lib/eggs/injected_tab_bar.dart | 4 +- .../generators/plugins/pb_plugin_node.dart | 2 - .../prototyping/pb_dest_holder.dart | 10 +-- .../entities/alignments/flexible.dart | 8 +- .../alignments/injected_positioned.dart | 10 +-- .../entities/alignments/padding.dart | 6 +- .../entities/alignments/spacer.dart | 9 +- .../entities/inherited_bitmap.dart | 10 +-- .../entities/inherited_circle.dart | 20 +---- .../entities/inherited_container.dart | 20 +---- .../entities/inherited_oval.dart | 13 +-- .../entities/inherited_polygon.dart | 15 +--- .../entities/inherited_scaffold.dart | 2 +- .../entities/inherited_shape_group.dart | 7 +- .../entities/inherited_shape_path.dart | 9 +- .../entities/inherited_star.dart | 15 +--- .../entities/inherited_text.dart | 10 +-- .../entities/inherited_triangle.dart | 15 +--- .../entities/injected_container.dart | 19 +---- .../entities/layouts/column.dart | 2 +- .../entities/layouts/row.dart | 2 +- .../entities/layouts/stack.dart | 2 +- .../layouts/temp_group_layout_node.dart | 2 +- .../entities/pb_deny_list_node.dart | 9 +- .../entities/pb_shared_instance.dart | 7 +- .../entities/pb_shared_master_node.dart | 2 +- .../subclasses/pb_intermediate_node.dart | 7 +- .../helpers/child_strategy.dart | 83 +++++++++++++++++++ .../pb_symbol_master_params.dart | 6 +- 33 files changed, 189 insertions(+), 169 deletions(-) create mode 100644 lib/interpret_and_optimize/helpers/child_strategy.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 1e65f7f0..755a8019 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; @@ -168,11 +170,10 @@ class AITServiceBuilder { return _intermediateTree; } catch (e) { MainInfo().captureException(e); - log.error('PBDL Conversion was not possible'); + log.error('PBDL Conversion was not possible because of - \n$e'); - /// Exit from Parabeac-Core - throw Error(); - } + exit(1); + } } Future build() async { diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index d439e874..e9a325bb 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -41,26 +41,26 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { } @override - void addChild(PBIntermediateNode node) { + void addChild(node) { if (node is PBInheritedIntermediate) { if ((node as PBInheritedIntermediate) .originalRef .name .contains('')) { - getAttributeNamed('leading').attributeNode = node; + getAttributeNamed('leading').attributeNode = node as PBIntermediateNode; } if ((node as PBInheritedIntermediate) .originalRef .name .contains('')) { - getAttributeNamed('actions').attributeNode = node; + getAttributeNamed('actions').attributeNode = node as PBIntermediateNode; } if ((node as PBInheritedIntermediate) .originalRef .name .contains('')) { - getAttributeNamed('title').attributeNode = node; + getAttributeNamed('title').attributeNode = node as PBIntermediateNode; } } diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index 2799a9d3..2a6f23f5 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -15,6 +16,9 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; + + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); InjectedBackArrow( Point topLeftCorner, Point bottomRightCorner, this.UUID, String name, @@ -23,8 +27,6 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { generator = PBBackArrowGenerator(); } - @override - void addChild(PBIntermediateNode node) {} @override void alignChild() {} diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 4193026a..db17168d 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:uuid/uuid.dart'; @@ -16,6 +17,9 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { @override PrototypeNode prototypeNode; + @override + ChildrenStrategy childrenStrategy = OneChildStrategy('child'); + Tab( Point topLeftCorner, Point bottomRightCorner, @@ -28,11 +32,6 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { generator = PBTabGenerator(); } - @override - void addChild(PBIntermediateNode node) { - child = node; - } - @override String semanticName; diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index b2a77f55..5b4b574d 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -33,14 +33,14 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { } @override - void addChild(PBIntermediateNode node) { + void addChild(node) { if (node is PBInheritedIntermediate) { if ((node as PBInheritedIntermediate) .originalRef .name .contains('')) { assert(node is! Tab, 'node should be a Tab'); - getAttributeNamed('tabs').attributeNodes.add(node); + getAttributeNamed('tabs').attributeNodes.add(node as PBIntermediateNode); } } diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index 15c402bd..abb89aa0 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -26,6 +26,4 @@ abstract class PBEgg extends PBVisualIntermediateNode { void extractInformation(DesignNode incomingNode); - @override - void addChild(PBIntermediateNode node); } diff --git a/lib/generation/prototyping/pb_dest_holder.dart b/lib/generation/prototyping/pb_dest_holder.dart index 52e5fc0e..700b0981 100644 --- a/lib/generation/prototyping/pb_dest_holder.dart +++ b/lib/generation/prototyping/pb_dest_holder.dart @@ -1,12 +1,16 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class PBDestHolder extends PBIntermediateNode { PrototypeNode pNode; + @override + ChildrenStrategy childrenStrategy = OneChildStrategy('child'); + PBDestHolder(Point topLeftCorner, Point bottomRightCorner, String UUID, this.pNode, PBContext currentContext) : super(topLeftCorner, bottomRightCorner, UUID, '', @@ -14,10 +18,4 @@ class PBDestHolder extends PBIntermediateNode { generator = PBPrototypeGenerator(pNode); } - @override - void addChild(PBIntermediateNode node) { - assert(child == null, - 'Tried assigning multiple children to class [PBDestHolder]'); - child = node; - } } diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index 28879f9a..575b6ead 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_flexible_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class Flexible extends PBVisualIntermediateNode { @@ -13,6 +14,7 @@ class Flexible extends PBVisualIntermediateNode { final String UUID; @override + ChildrenStrategy childrenStrategy = OneChildStrategy('child'); //TODO: Find a way to make currentContext required //without breaking the json serializable @@ -40,12 +42,6 @@ class Flexible extends PBVisualIntermediateNode { @override Point bottomRightCorner; - @override - void addChild(PBIntermediateNode node) { - assert(child == null, 'Tried adding another child to Flexible'); - child = node; - } - @override void alignChild() {} } diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index 8ba528bc..00e896a6 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -2,6 +2,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_positioned import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -14,6 +15,9 @@ class InjectedPositioned extends PBIntermediateNode final String UUID; final PositionedValueHolder valueHolder; + + @override + ChildrenStrategy childrenStrategy = OneChildStrategy('child'); InjectedPositioned( this.UUID, { @@ -25,12 +29,6 @@ class InjectedPositioned extends PBIntermediateNode generator = PBPositionedGenerator(); } - @override - void addChild(PBIntermediateNode node) { - assert(child == null, - 'Tried assigning multiple children to class [InjectedPositioned]'); - child = node; - } } /// Class to help us communicate and manipulate positioning values. diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index 6e748734..127f0d92 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -2,6 +2,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_padding_ge import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -23,6 +24,9 @@ class Padding extends PBVisualIntermediateNode { PBIntermediateConstraints childToParentConstraints; + @override + ChildrenStrategy childrenStrategy = OneChildStrategy('child'); + Padding( this.UUID, this.childToParentConstraints, { @@ -38,7 +42,7 @@ class Padding extends PBVisualIntermediateNode { } @override - void addChild(PBIntermediateNode node) { + void addChild(node) { assert(child == null, 'Padding cannot accept multiple children.'); child = node; diff --git a/lib/interpret_and_optimize/entities/alignments/spacer.dart b/lib/interpret_and_optimize/entities/alignments/spacer.dart index 162fc4ed..2d39c3aa 100644 --- a/lib/interpret_and_optimize/entities/alignments/spacer.dart +++ b/lib/interpret_and_optimize/entities/alignments/spacer.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_spacer_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class Spacer extends PBVisualIntermediateNode { @@ -11,6 +12,9 @@ class Spacer extends PBVisualIntermediateNode { @override PBContext currentContext; + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + Spacer(topLeftCorner, bottomRightCorner, this.UUID, {this.flex, this.currentContext}) : super(topLeftCorner, bottomRightCorner, currentContext, '', @@ -18,11 +22,6 @@ class Spacer extends PBVisualIntermediateNode { generator = PBSpacerGenerator(); } - @override - void addChild(PBIntermediateNode node) { - assert(false, 'Spacer cannot accept any children.'); - } - @override void alignChild() {} } diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index f27c6c70..47fbab7e 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -20,6 +21,9 @@ class InheritedBitmap extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + var log = Logger('Inherited Bitmap'); String referenceImage; @@ -59,12 +63,6 @@ class InheritedBitmap extends PBVisualIntermediateNode originalRef.UUID, '${MainInfo().outputPath}assets/images'); } - @override - void addChild(PBIntermediateNode node) { - assert(true, 'Tried adding a child to InheritedBitmap.'); - return; - } - @override void alignChild() { return; diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 46026009..6ab153e3 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -17,6 +18,9 @@ class InheritedCircle extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; + @override + ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); + InheritedCircle(this.originalRef, Point bottomRightCorner, Point topLeftCorner, String name, {PBContext currentContext, Point alignX, Point alignY}) @@ -36,22 +40,6 @@ class InheritedCircle extends PBVisualIntermediateNode auxiliaryData.borderInfo['shape'] = 'circle'; } - @override - void addChild(PBIntermediateNode node) { - if (child is TempGroupLayoutNode) { - child.addChild(node); - return; - } - // If there's multiple children add a temp group so that layout service lays the children out. - if (child != null) { - var temp = TempGroupLayoutNode(null, currentContext, node.name); - temp.addChild(child); - temp.addChild(node); - child = temp; - } - child = node; - } - @override void alignChild() { var padding = Padding('', child.constraints, diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 5ae7c407..6152c373 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -23,6 +24,9 @@ class InheritedContainer extends PBVisualIntermediateNode bool isBackgroundVisible = true; + @override + ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); + InheritedContainer(this.originalRef, Point topLeftCorner, Point bottomRightCorner, String name, {double alignX, @@ -64,22 +68,6 @@ class InheritedContainer extends PBVisualIntermediateNode 'A null original reference was sent to an PBInheritedIntermediate Node'); } - @override - void addChild(PBIntermediateNode node) { - if (child is TempGroupLayoutNode) { - child.addChild(node); - return; - } - // If there's multiple children add a temp group so that layout service lays the children out. - if (child != null) { - var temp = TempGroupLayoutNode(null, currentContext, node.name); - temp.addChild(child); - temp.addChild(node); - child = temp; - } - child = node; - } - @override void alignChild() { if (child != null) { diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index fe4d2a6a..861c67f6 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -19,6 +20,9 @@ class InheritedOval extends PBVisualIntermediateNode var originalRef; var log = Logger('Layout Generation Service'); + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + @override PrototypeNode prototypeNode; @@ -54,15 +58,6 @@ class InheritedOval extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - @override - void addChild(PBIntermediateNode node) { - // Hopefully we converted the SVG correctly. Most likely this will get called to add the shapes but this is unnecessary. - if (node is InheritedShapePath) { - return; - } - log.error( - 'Child with type ${node.runtimeType} could not be added as a child.'); - } @override void alignChild() { diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index 30e18e41..b22dd61c 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -20,6 +21,9 @@ class InheritedPolygon extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + InheritedPolygon(this.originalRef, String name, {Uint8List image, PBContext currentContext, @@ -51,17 +55,6 @@ class InheritedPolygon extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - @override - void addChild(PBIntermediateNode node) { - // Hopefully we converted the SVG correctly. Most likely this will get called to add the shapes but this is unnecessary. - if (node is InheritedShapePath) { - return; - } - assert(false, - 'Child with type ${node.runtimeType} could not be added as a child.'); - return; - } - @override void alignChild() { // Images don't hae children. diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 444daa73..a66373f7 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -83,7 +83,7 @@ class InheritedScaffold extends PBVisualIntermediateNode } @override - void addChild(PBIntermediateNode node) { + void addChild( node) { if (node is PBSharedInstanceIntermediateNode) { if (node.originalRef.name.contains('')) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index 83877f53..2f9039c1 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -20,6 +21,9 @@ class InheritedShapeGroup extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + InheritedShapeGroup(this.originalRef, String name, {Uint8List image, PBContext currentContext, @@ -52,9 +56,6 @@ class InheritedShapeGroup extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - @override - void addChild(PBIntermediateNode node) => null; - @override void alignChild() { // Images don't have children. diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 19517ffe..2340e065 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -11,6 +11,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -23,6 +24,9 @@ class InheritedShapePath extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + InheritedShapePath(this.originalRef, String name, {Uint8List image, PBContext currentContext, @@ -96,11 +100,6 @@ class InheritedShapePath extends PBVisualIntermediateNode return isVertical || isHorizontal; } - @override - void addChild(PBIntermediateNode node) { - return; - } - @override void alignChild() {} } diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index 59edb482..54443a1c 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -19,6 +20,9 @@ class InheritedStar extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; + + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); InheritedStar(this.originalRef, String name, {Uint8List image, @@ -52,17 +56,6 @@ class InheritedStar extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - @override - void addChild(PBIntermediateNode node) { - // Hopefully we converted the SVG correctly. Most likely this will get called to add the shapes but this is unnecessary. - if (node is InheritedShapePath) { - return; - } - assert(false, - 'Child with type ${node.runtimeType} could not be added as a child.'); - return; - } - @override void alignChild() { // Images don't have children. diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 47b01a82..8451cf48 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -15,6 +16,9 @@ class InheritedText extends PBVisualIntermediateNode ///For the generator to strip out the quotation marks. bool isTextParameter = false; + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + @override var originalRef; @@ -75,12 +79,6 @@ class InheritedText extends PBVisualIntermediateNode return text.replaceAll('\$', '\\\$'); } - @override - void addChild(PBIntermediateNode node) { - assert(true, 'Adding a child to InheritedText should not be possible.'); - return; - } - @override void alignChild() { // Text don't have children. diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 08def46f..24e43e83 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -20,6 +21,9 @@ class InheritedTriangle extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + InheritedTriangle(this.originalRef, String name, {Uint8List image, PBContext currentContext, @@ -52,17 +56,6 @@ class InheritedTriangle extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - @override - void addChild(PBIntermediateNode node) { - // Hopefully we converted the SVG correctly. Most likely this will get called to add the shapes but this is unnecessary. - if (node is InheritedShapePath) { - return; - } - assert(false, - 'Child with type ${node.runtimeType} could not be added as a child.'); - return; - } - @override void alignChild() { // Images don't have children. diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 05678e94..13e82829 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -15,6 +16,9 @@ class InjectedContainer extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; + @override + ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); + InjectedContainer( Point bottomRightCorner, Point topLeftCorner, @@ -33,21 +37,6 @@ class InjectedContainer extends PBVisualIntermediateNode }; } - @override - void addChild(PBIntermediateNode node) { - if (child is TempGroupLayoutNode) { - child.addChild(node); - return; - } - // If there's multiple children add a temp group so that layout service lays the children out. - if (child != null) { - var temp = TempGroupLayoutNode(null, currentContext, name); - temp.addChild(child); - temp.addChild(node); - child = temp; - } - child = node; - } @override void alignChild() { diff --git a/lib/interpret_and_optimize/entities/layouts/column.dart b/lib/interpret_and_optimize/entities/layouts/column.dart index 5fc2bf29..4384e8da 100644 --- a/lib/interpret_and_optimize/entities/layouts/column.dart +++ b/lib/interpret_and_optimize/entities/layouts/column.dart @@ -91,7 +91,7 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { } @override - void addChild(PBIntermediateNode node) => addChildToLayout(node); + void addChild(node) => addChildToLayout(node); /// Invert method for Column alignment void _invertAlignment() { diff --git a/lib/interpret_and_optimize/entities/layouts/row.dart b/lib/interpret_and_optimize/entities/layouts/row.dart index 71bab952..dd191999 100644 --- a/lib/interpret_and_optimize/entities/layouts/row.dart +++ b/lib/interpret_and_optimize/entities/layouts/row.dart @@ -33,7 +33,7 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { } @override - void addChild(PBIntermediateNode node) => addChildToLayout(node); + void addChild(node) => addChildToLayout(node); @override void alignChildren() { diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index af7bfb56..d72f50cd 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -31,7 +31,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { } @override - void addChild(PBIntermediateNode node) => addChildToLayout(node); + void addChild(node) => addChildToLayout(node); /// Do we need to subtract some sort of offset? Maybe child.topLeftCorner.x - topLeftCorner.x? @override diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index 395fecd4..a1b662d2 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -27,7 +27,7 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode } @override - void addChild(PBIntermediateNode node) { + void addChild(node) { addChildToLayout(node); } diff --git a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart index 0b01fd7a..22efa1a1 100644 --- a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart +++ b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart @@ -1,9 +1,13 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; /// A node that should not be converted to intermediate. class PBDenyListNode extends PBIntermediateNode { + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + PBDenyListNode(Point topLeftCorner, Point bottomRightCorner, PBContext currentContext, String name, {String UUID}) @@ -15,9 +19,4 @@ class PBDenyListNode extends PBIntermediateNode { currentContext: currentContext, ); - @override - void addChild(PBIntermediateNode node) { - // Unclear whether we should even go into the children if we run into a Deny List node. - return; - } } diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index d4dbbcc8..b6201a2e 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -37,6 +38,9 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @override PrototypeNode prototypeNode; + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + List overrideValues; // quick lookup based on UUID_type Map overrideValuesMap = {}; @@ -73,9 +77,6 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode ..removeWhere((v) => v == null || v.value == null); } - @override - void addChild(PBIntermediateNode node) {} - @override void alignChild() { if (child != null) { diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 98c1b84a..22e0f4fd 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -107,7 +107,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode } @override - void addChild(PBIntermediateNode node) => + void addChild(node) => child == null ? child = node : children = [node]; @override diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 75f34243..e67ed16a 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; @@ -36,6 +37,8 @@ abstract class PBIntermediateNode extends TraversableNode { @override List get children => [child]; + ChildrenStrategy childrenStrategy = OneChildStrategy('child'); + /// Gets the [PBIntermediateNode] at attribute `child` PBIntermediateNode get child => getAttributeNamed('child')?.attributeNode; @@ -136,5 +139,7 @@ abstract class PBIntermediateNode extends TraversableNode { } /// Adds child to node. - void addChild(PBIntermediateNode node); + void addChild(node){ + childrenStrategy.addChild(this, node); + } } diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart new file mode 100644 index 00000000..4275f9c5 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -0,0 +1,83 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:quick_log/quick_log.dart'; + + +abstract class ChildrenStrategy { + Logger log; + //TODO: will be used in the migrations to attributes + final String attributeName; + final bool overwridable; + ChildrenStrategy(this.attributeName, this.overwridable) { + log = Logger(runtimeType.toString()); + } + void addChild(PBIntermediateNode target, dynamic children); +} + +class OneChildStrategy extends ChildrenStrategy { + OneChildStrategy(String attributeName, [bool overridable = false]) + : super(attributeName, overridable); + + @override + void addChild(PBIntermediateNode target, dynamic child) { + if (child is PBIntermediateNode) { + child.parent = target; + target.child = child; + } else { + log.warning( + 'Tried adding ${child.runtimeType.toString()} to ${target.runtimeType.toString()}'); + } + } +} + +class MultipleChildStrategy extends ChildrenStrategy { + MultipleChildStrategy(String attributeName, [bool overridable]) + : super(attributeName, overridable); + + @override + void addChild(PBIntermediateNode target, children) { + if (children is List) { + children.forEach((child) { + child.parent = target; + target.children.add(child); + }); + } else if (children is PBIntermediateNode) { + target.child = children; + } + } +} + +class NoChildStrategy extends ChildrenStrategy { + NoChildStrategy([bool overridable]) + : super('N/A', overridable); + + @override + void addChild(PBIntermediateNode target, children) { + if (children != null) { + log.warning( + 'Tried adding ${children.runtimeType.toString()} to ${target.runtimeType.toString()}'); + } + } +} + +class TempChildrenStrategy extends ChildrenStrategy{ + TempChildrenStrategy(String attributeName,[ bool overwridable]) : super(attributeName, overwridable); + + @override + void addChild(PBIntermediateNode target, children) { + if(target.child is TempGroupLayoutNode){ + target.child.addChild(children); + } + else if (target.child != null){ + var temp = TempGroupLayoutNode(null, target.currentContext, children.name); + temp.addChild(target.child); + temp.addChild(children); + temp.parent = target; + target.child = temp; + } + else if(children is PBIntermediateNode){ + children.parent = target; + target.child = children; + } + } +} diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart index ca5727b2..3ff48f41 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart @@ -2,6 +2,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; @@ -18,6 +19,9 @@ class PBSymbolMasterParameter extends PBVisualIntermediateNode PBContext context; + @override + ChildrenStrategy childrenStrategy = NoChildStrategy(); + PBSymbolMasterParameter( String name, this.type, @@ -41,8 +45,6 @@ class PBSymbolMasterParameter extends PBVisualIntermediateNode return PBIntermediateNode; } - @override - void addChild(PBIntermediateNode node) {} @override void alignChild() {} From ee18eb1f6e3f3ba1c9829c8fc5208cb2f5782abf Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 21 Jul 2021 17:24:55 -0600 Subject: [PATCH 244/404] WIP added method that returns the distance between two nodes. --- .../helpers/pb_intermediate_node_tree.dart | 50 +++++++++++++++++++ .../dfs_iterator_test.dart | 20 ++++++++ .../services/interpret_test.dart | 1 - test/lib/layouts/layout_post_rules_test.dart | 2 +- 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 19820d43..735c0c67 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -4,6 +4,8 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_n import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; import 'package:recase/recase.dart'; +import 'package:tuple/tuple.dart'; +import "dart:collection"; import 'package:uuid/uuid.dart'; enum TREE_TYPE { @@ -99,6 +101,52 @@ class PBIntermediateTree extends Iterable { bool isHomeScreen() => isScreen() && (rootNode as InheritedScaffold).isHomeScreen; + + /// Finding the depth of the [node] in relation to the [rootNode]. + int depthOf(node) { + return dist(rootNode, node); + } + + /// Find the distance between [source] and [target], where the [source] is an + /// ancestor of [target]. + /// + /// IF [source] IS NOT AN ANCESTOR OF [target], THEN ITS GOING TO RETURN `-2`. + /// This is because the nodes of the tree dont have an out going edge + /// pointing towards its parents, all directed edges are going down the tree. + int dist(PBIntermediateNode source, PBIntermediateNode target, + {int edgeCost = 1}) { + if (!contains(target)) { + throw Error(); + } + + var maxPathLength = length + 1; + + Queue queue = Queue(); + var dist = { + for (var node in toList()) node: maxPathLength + }; + + queue.add(source); + dist[source] = 0; + + while (queue.isNotEmpty) { + var node = queue.removeFirst(); + + for (var outNode in node?.children ?? []) { + if (dist[outNode] != maxPathLength) { + continue; + } + + var newDist = dist[node] + edgeCost; + if (newDist < dist[outNode]) { + dist[outNode] = newDist; + queue.add(outNode); + } + } + } + return dist[target] == maxPathLength ? -1 : dist[target]; + } + @override Iterator get iterator => IntermediateDFSIterator(this); } @@ -110,5 +158,7 @@ class PBIntermediateTree extends Iterable { /// children by using the [IntermediateDFSIterator]. Furthermore, this allows the /// [PBIntermediateTree] to traverse through its nodes, leveraging the dart methods. abstract class TraversableNode { + E parent; + int treeLevel; List children; } diff --git a/test/lib/interpret_and_optimize/dfs_iterator_test.dart b/test/lib/interpret_and_optimize/dfs_iterator_test.dart index 78c3e4fa..efe4e4dd 100644 --- a/test/lib/interpret_and_optimize/dfs_iterator_test.dart +++ b/test/lib/interpret_and_optimize/dfs_iterator_test.dart @@ -12,6 +12,13 @@ void main() { PBIntermediateTree tree; group('Testing the PBIntermediateTree', () { setUp(() { + ///This is the tree that is going to be build: + /// R_123 + /// | + /// [P_0, P_1, P_2, P_3, P_4] + /// | | | | | + /// [C_0][C_1][C_2][C_3][C_4] + numberOfContainers = 10; containerList = List.generate((numberOfContainers ~/ 2), (idx) { var container = MockContainer(); @@ -39,5 +46,18 @@ void main() { expect(tree.length, numberOfContainers); expect(tree.first, rootNode); }); + + test('Testing [PBIntermediateTree.dist] function, see if it gives the correct distance between two nodes', (){ + var child = tree.firstWhere((node) => node.UUID == 'C_0'); + expect(child, isNotNull); + expect(tree.depftOf(child), 2); + + var parent = tree.firstWhere((node) => node.UUID == 'P_0'); + expect(parent, isNotNull); + expect(tree.depftOf(parent), 1); + + expect(rootNode, isNotNull); + expect(tree.depftOf(rootNode), 0); + }); }); } diff --git a/test/lib/interpret_and_optimize/services/interpret_test.dart b/test/lib/interpret_and_optimize/services/interpret_test.dart index 14e6a09d..3ffce263 100644 --- a/test/lib/interpret_and_optimize/services/interpret_test.dart +++ b/test/lib/interpret_and_optimize/services/interpret_test.dart @@ -10,7 +10,6 @@ import 'package:parabeac_core/input/sketch/helper/sketch_page.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_project.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_screen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; diff --git a/test/lib/layouts/layout_post_rules_test.dart b/test/lib/layouts/layout_post_rules_test.dart index cc03f0e4..0ec1d6d3 100644 --- a/test/lib/layouts/layout_post_rules_test.dart +++ b/test/lib/layouts/layout_post_rules_test.dart @@ -11,7 +11,7 @@ class InheritedContainerMockWrapper extends Mock implements InheritedContainer { @override var child; @override - void addChild(PBIntermediateNode node) { + void addChild(node) { child = node; } } From b31c0c6092433a3d232e883d87f1f9ecad212cf0 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 21 Jul 2021 17:24:55 -0600 Subject: [PATCH 245/404] WIP added method that returns the distance between two nodes. --- .../helpers/pb_intermediate_node_tree.dart | 50 +++++++++++++++++++ .../dfs_iterator_test.dart | 20 ++++++++ .../services/interpret_test.dart | 1 - test/lib/layouts/layout_post_rules_test.dart | 2 +- 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 19820d43..735c0c67 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -4,6 +4,8 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_n import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; import 'package:recase/recase.dart'; +import 'package:tuple/tuple.dart'; +import "dart:collection"; import 'package:uuid/uuid.dart'; enum TREE_TYPE { @@ -99,6 +101,52 @@ class PBIntermediateTree extends Iterable { bool isHomeScreen() => isScreen() && (rootNode as InheritedScaffold).isHomeScreen; + + /// Finding the depth of the [node] in relation to the [rootNode]. + int depthOf(node) { + return dist(rootNode, node); + } + + /// Find the distance between [source] and [target], where the [source] is an + /// ancestor of [target]. + /// + /// IF [source] IS NOT AN ANCESTOR OF [target], THEN ITS GOING TO RETURN `-2`. + /// This is because the nodes of the tree dont have an out going edge + /// pointing towards its parents, all directed edges are going down the tree. + int dist(PBIntermediateNode source, PBIntermediateNode target, + {int edgeCost = 1}) { + if (!contains(target)) { + throw Error(); + } + + var maxPathLength = length + 1; + + Queue queue = Queue(); + var dist = { + for (var node in toList()) node: maxPathLength + }; + + queue.add(source); + dist[source] = 0; + + while (queue.isNotEmpty) { + var node = queue.removeFirst(); + + for (var outNode in node?.children ?? []) { + if (dist[outNode] != maxPathLength) { + continue; + } + + var newDist = dist[node] + edgeCost; + if (newDist < dist[outNode]) { + dist[outNode] = newDist; + queue.add(outNode); + } + } + } + return dist[target] == maxPathLength ? -1 : dist[target]; + } + @override Iterator get iterator => IntermediateDFSIterator(this); } @@ -110,5 +158,7 @@ class PBIntermediateTree extends Iterable { /// children by using the [IntermediateDFSIterator]. Furthermore, this allows the /// [PBIntermediateTree] to traverse through its nodes, leveraging the dart methods. abstract class TraversableNode { + E parent; + int treeLevel; List children; } diff --git a/test/lib/interpret_and_optimize/dfs_iterator_test.dart b/test/lib/interpret_and_optimize/dfs_iterator_test.dart index 78c3e4fa..0e32b59f 100644 --- a/test/lib/interpret_and_optimize/dfs_iterator_test.dart +++ b/test/lib/interpret_and_optimize/dfs_iterator_test.dart @@ -12,6 +12,13 @@ void main() { PBIntermediateTree tree; group('Testing the PBIntermediateTree', () { setUp(() { + ///This is the tree that is going to be build: + /// R_123 + /// | + /// [P_0, P_1, P_2, P_3, P_4] + /// | | | | | + /// [C_0][C_1][C_2][C_3][C_4] + numberOfContainers = 10; containerList = List.generate((numberOfContainers ~/ 2), (idx) { var container = MockContainer(); @@ -39,5 +46,18 @@ void main() { expect(tree.length, numberOfContainers); expect(tree.first, rootNode); }); + + test('Testing [PBIntermediateTree.dist] function, see if it gives the correct distance between two nodes', (){ + var child = tree.firstWhere((node) => node.UUID == 'C_0'); + expect(child, isNotNull); + expect(tree.depthOf(child), 2); + + var parent = tree.firstWhere((node) => node.UUID == 'P_0'); + expect(parent, isNotNull); + expect(tree.depthOf(parent), 1); + + expect(rootNode, isNotNull); + expect(tree.depthOf(rootNode), 0); + }); }); } diff --git a/test/lib/interpret_and_optimize/services/interpret_test.dart b/test/lib/interpret_and_optimize/services/interpret_test.dart index 14e6a09d..3ffce263 100644 --- a/test/lib/interpret_and_optimize/services/interpret_test.dart +++ b/test/lib/interpret_and_optimize/services/interpret_test.dart @@ -10,7 +10,6 @@ import 'package:parabeac_core/input/sketch/helper/sketch_page.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_project.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_screen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; diff --git a/test/lib/layouts/layout_post_rules_test.dart b/test/lib/layouts/layout_post_rules_test.dart index cc03f0e4..0ec1d6d3 100644 --- a/test/lib/layouts/layout_post_rules_test.dart +++ b/test/lib/layouts/layout_post_rules_test.dart @@ -11,7 +11,7 @@ class InheritedContainerMockWrapper extends Mock implements InheritedContainer { @override var child; @override - void addChild(PBIntermediateNode node) { + void addChild(node) { child = node; } } From 938f7eeba060a3699f6887d96d524c4401f2d96a Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 21 Jul 2021 19:04:31 -0600 Subject: [PATCH 246/404] WIP adjusted the layout node and enforced context as constructor parameter --- .../entities/inherited_scaffold.dart | 5 ++- .../entities/layouts/column.dart | 16 ++-------- .../entities/layouts/row.dart | 10 ++---- .../entities/layouts/stack.dart | 29 +++++++++++------ .../layouts/temp_group_layout_node.dart | 2 -- .../pb_layout_intermediate_node.dart | 10 +++--- .../helpers/pb_intermediate_node_tree.dart | 5 +-- .../pb_constraint_generation_service.dart | 8 +---- .../pb_layout_generation_service.dart | 6 ++-- .../pb_visual_generation_service.dart | 32 +++++++++---------- 10 files changed, 52 insertions(+), 71 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index a66373f7..324a2604 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -117,9 +117,8 @@ class InheritedScaffold extends PBVisualIntermediateNode child.addChild(node); } else { var stack = PBIntermediateStackLayout( - node.name, - '', - currentContext: currentContext, + currentContext, + name: node.name ); stack.addChild(node); child = stack; diff --git a/lib/interpret_and_optimize/entities/layouts/column.dart b/lib/interpret_and_optimize/entities/layouts/column.dart index 4384e8da..3b54151b 100644 --- a/lib/interpret_and_optimize/entities/layouts/column.dart +++ b/lib/interpret_and_optimize/entities/layouts/column.dart @@ -9,7 +9,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/handle_flex.dart'; -import 'package:uuid/uuid.dart'; ///Colum contains nodes that are all `vertical` to each other, without overlapping eachother @@ -22,20 +21,12 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { ColumnOverlappingException(), ]; - @override - final String UUID; - - @override - PBContext currentContext; - @override PrototypeNode prototypeNode; PBIntermediateColumnLayout( - String name, { - this.currentContext, - this.UUID, - }) : super(COLUMN_RULES, COLUMN_EXCEPTIONS, currentContext, name) { + PBContext currentContext, + {String name}) : super(COLUMN_RULES, COLUMN_EXCEPTIONS, currentContext, name) { generator = PBColumnGenerator(); } @@ -83,8 +74,7 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { - var col = PBIntermediateColumnLayout(name, - currentContext: currentContext, UUID: Uuid().v4()); + var col = PBIntermediateColumnLayout(currentContext, name: name); col.prototypeNode = prototypeNode; children.forEach((child) => col.addChild(child)); return col; diff --git a/lib/interpret_and_optimize/entities/layouts/row.dart b/lib/interpret_and_optimize/entities/layouts/row.dart index dd191999..5671e211 100644 --- a/lib/interpret_and_optimize/entities/layouts/row.dart +++ b/lib/interpret_and_optimize/entities/layouts/row.dart @@ -9,7 +9,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:uuid/uuid.dart'; ///Row contains nodes that are all `horizontal` to each other, without overlapping eachother @@ -20,14 +19,10 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { RowOverlappingException() ]; - //TODO: remove all overriden UUID - @override - final String UUID; - @override PrototypeNode prototypeNode; - PBIntermediateRowLayout(String name, this.UUID, {PBContext currentContext}) + PBIntermediateRowLayout(PBContext currentContext, {String name}) : super(ROW_RULES, ROW_EXCEPTIONS, currentContext, name) { generator = PBRowGenerator(); } @@ -85,8 +80,7 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { - var row = PBIntermediateRowLayout(name, Uuid().v4(), - currentContext: currentContext); + var row = PBIntermediateRowLayout(currentContext, name: name); row.prototypeNode = prototypeNode; children.forEach((child) => row.addChild(child)); return row; diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index d72f50cd..9048eca5 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -13,19 +13,13 @@ import 'package:uuid/uuid.dart'; class PBIntermediateStackLayout extends PBLayoutIntermediateNode { static final List STACK_RULES = [OverlappingNodesLayoutRule()]; - @override - PBContext currentContext; - - @override - final String UUID; - @override Map alignment = {}; @override PrototypeNode prototypeNode; - PBIntermediateStackLayout(String name, this.UUID, {this.currentContext}) + PBIntermediateStackLayout(PBContext currentContext, {String name}) : super(STACK_RULES, [], currentContext, name) { generator = PBStackGenerator(); } @@ -33,6 +27,22 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { @override void addChild(node) => addChildToLayout(node); + @override + void resize() { + var depth = currentContext.tree?.depthOf(this); + + /// Since there are cases where [Stack] are being created, and + /// childrend are being populated, and consequently [Stack.resize] is being + /// called, then [depth] could be null. [depth] is null when the [PBIntermediateTree] + /// has not finished creating and converting PBDL nodes into [PBIntermediateNode]. + if (depth != null && depth <= 2 && depth >= 0) { + topLeftCorner = currentContext.canvasTLC; + bottomRightCorner = currentContext.canvasBRC; + } else { + super.resize(); + } + } + /// Do we need to subtract some sort of offset? Maybe child.topLeftCorner.x - topLeftCorner.x? @override void alignChildren() { @@ -72,9 +82,8 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { PBContext currentContext, String name) { /// The width of this stack must be the full width of the Scaffold or Artboard. As discussed, at some point we can change this but for now, this makes the most sense. var stack = PBIntermediateStackLayout( - name, - Uuid().v4(), - currentContext: currentContext, + currentContext, + name: name ); stack.prototypeNode = prototypeNode; children.forEach((child) => stack.addChild(child)); diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index a1b662d2..31e1d0d4 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -13,8 +13,6 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode final originalRef; @override PrototypeNode prototypeNode; - @override - String get UUID => originalRef.UUID; TempGroupLayoutNode(this.originalRef, PBContext currentContext, String name, {topLeftCorner, bottomRightCorner, PBDLConstraints constraints}) diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index 66601d1d..f5e40f4b 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -51,7 +51,7 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode void replaceChildren(List children) { if (children.isNotEmpty) { getAttributeNamed('children')?.attributeNodes = children; - _resize(); + resize(); } else { PBIntermediateNode.logger.warning( 'Trying to add a list of children to the $runtimeType that is either null or empty'); @@ -71,10 +71,10 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode ///Add node to child void addChildToLayout(PBIntermediateNode node) { getAttributeNamed('children').attributeNodes.add(node); - _resize(); + resize(); } - void _resize() { + void resize() { if (children.isEmpty) { PBIntermediateNode.logger .warning('There should be children in the layout so it can resize.'); @@ -99,7 +99,7 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode if (children.contains(node)) { children.remove(node); } - _resize(); + resize(); return false; } @@ -171,4 +171,4 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode } } } -} +} \ No newline at end of file diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 77bd97ca..371a880f 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -110,13 +110,14 @@ class PBIntermediateTree extends Iterable { /// Find the distance between [source] and [target], where the [source] is an /// ancestor of [target]. /// - /// IF [source] IS NOT AN ANCESTOR OF [target], THEN ITS GOING TO RETURN `-1`. + /// IF [source] IS NOT AN ANCESTOR OF [target] OR [target] IS + /// NOT PRESENT IN THE [PBIntermediateNode], THEN ITS GOING TO RETURN `-1`. /// This is because the nodes of the tree dont have an out going edge /// pointing towards its parents, all directed edges are going down the tree. int dist(PBIntermediateNode source, PBIntermediateNode target, {int edgeCost = 1}) { if (!contains(target)) { - throw Error(); + return -1; } var maxPathLength = length + 1; diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index c3c2b191..6846d391 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -4,25 +4,19 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dar import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; ///tree.where((element) => element != null).toList().reversed.map((e) => e.name).toList() class PBConstraintGenerationService implements AITHandler { - @override - PBContext currentContext; PBConstraintGenerationService(); /// Traverse to the bottom of the tree, and implement constraints to nodes that don't already contain it such as [InjectedContainer] and then work our way up the tree. /// Through Traversal, discover whether there are elements that will conflict on scaling, if so, change the layout to a Stack. Future implementConstraints(PBIntermediateTree tree, PBContext context) { - currentContext = context; if (tree.rootNode == null) { return Future.value(tree); } @@ -50,7 +44,7 @@ class PBConstraintGenerationService implements AITHandler { if (_shouldLayoutBeStack(node)) { /// Change Layout to Stack var newStackReplacement = - PBIntermediateStackLayout(node.UUID, node.name); + PBIntermediateStackLayout(context, name: node.name); node.attributes.forEach((element) { newStackReplacement.addAttribute(element); }); diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 29b50913..c6982dee 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -14,7 +14,6 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:tuple/tuple.dart'; -import 'package:uuid/uuid.dart'; /// PBLayoutGenerationService: /// Inject PBLayoutIntermediateNode to a PBIntermediateNode Tree that signifies the grouping of PBItermediateNodes in a given direction. There should not be any PBAlignmentIntermediateNode in the input tree. @@ -47,9 +46,8 @@ class PBLayoutGenerationService implements AITHandler { // 'row': PBIntermediateRowLayout('', Uuid().v4(), // currentContext: currentContext), 'stack': PBIntermediateStackLayout( - '', - Uuid().v4(), - ), + null, + ), }; for (var layoutType diff --git a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart index 9985d2bd..8cff18ab 100644 --- a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart @@ -54,7 +54,6 @@ class PBVisualGenerationService{ PBPluginListHelper().initPlugins(currentContext); var queue = []; - PBIntermediateNode rootIntermediateNode; queue.add(NodeTuple(originalRoot, null)); while (queue.isNotEmpty) { var currentNode = queue.removeAt(0); @@ -98,10 +97,10 @@ class PBVisualGenerationService{ _addToParent(currentNode.convertedParent, result); } - // If we haven't assigned the rootIntermediateNode, this must be the first node, aka root node. - rootIntermediateNode ??= result; - if(rootIntermediateNode != null){ - _extractScreenSize(rootIntermediateNode, currentContext); + // If we haven't assigned the tree.rootNode, this must be the first node, aka root node. + tree.rootNode ??= result; + if(tree.rootNode != null){ + _extractScreenSize(tree.rootNode, currentContext); } @@ -123,33 +122,32 @@ class PBVisualGenerationService{ if (originalRoot.prototypeNodeUUID != null) { var prototypeNode = PrototypeNode(originalRoot.prototypeNodeUUID); var destHolder = PBDestHolder( - rootIntermediateNode.topLeftCorner, - rootIntermediateNode.bottomRightCorner, - rootIntermediateNode.UUID, + tree.rootNode.topLeftCorner, + tree.rootNode.bottomRightCorner, + tree.rootNode.UUID, prototypeNode, - rootIntermediateNode.currentContext); - destHolder.addChild(rootIntermediateNode); + tree.rootNode.currentContext); + destHolder.addChild(tree.rootNode); tree.rootNode = destHolder; return Future.value(tree); } - tree.rootNode = rootIntermediateNode; return Future.value(tree); } ///Sets the size of the UI element. /// - ///We are assuming that since the [rootIntermediateNode] contains all of the nodes + ///We are assuming that since the [tree.rootNode] contains all of the nodes ///then it should represent the biggest screen size that encapsulates the entire UI elements. - void _extractScreenSize(PBIntermediateNode rootIntermediateNode, PBContext currentContext) { + void _extractScreenSize(PBIntermediateNode rootNode, PBContext currentContext) { if ((currentContext.screenBottomRightCorner == null && currentContext.screenTopLeftCorner == null) || (currentContext.screenBottomRightCorner != - rootIntermediateNode.bottomRightCorner || + rootNode.bottomRightCorner || currentContext.screenTopLeftCorner != - rootIntermediateNode.bottomRightCorner)) { + rootNode.bottomRightCorner)) { currentContext.screenBottomRightCorner = - rootIntermediateNode.bottomRightCorner; - currentContext.screenTopLeftCorner = rootIntermediateNode.topLeftCorner; + rootNode.bottomRightCorner; + currentContext.screenTopLeftCorner = rootNode.topLeftCorner; } } From 133820c35c8d37900eb7985c58e47fe890b9dc8e Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 21 Jul 2021 22:14:27 -0600 Subject: [PATCH 247/404] WIP added the correct resizing values for canvas in respect to the area left by scaffold.heigh - appbar.height --- .../entities/inherited_scaffold.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 324a2604..bfd716b0 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -87,8 +87,8 @@ class InheritedScaffold extends PBVisualIntermediateNode if (node is PBSharedInstanceIntermediateNode) { if (node.originalRef.name.contains('')) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); - // currentContext.focusAreaTLC = Point(currentContext.focusAreaTLC.x, - // currentContext.focusAreaBRC.y - node.topLeftCorner.y); + currentContext.canvasTLC = Point(currentContext.canvasTLC.x, + node.bottomRightCorner.y); return; } if (node.originalRef.name.contains('')) { @@ -100,8 +100,8 @@ class InheritedScaffold extends PBVisualIntermediateNode if (node is InjectedAppbar) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); - // currentContext.focusAreaBRC = Point(currentContext.focusAreaTLC.x, - // currentContext.focusAreaBRC.y - node.topLeftCorner.y); + currentContext.canvasTLC = Point(currentContext.canvasTLC.x, + node.bottomRightCorner.y); return; } if (node is InjectedTabBar) { From 38742cb3d3b3e1b008615f21ad839933b5a90d1e Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 22 Jul 2021 16:58:42 -0600 Subject: [PATCH 248/404] Not include custom egg on high level widgets --- .../helpers/pb_plugin_list_helper.dart | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index efb85e54..c2e3e654 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -1,3 +1,5 @@ +import 'package:parabeac_core/design_logic/artboard.dart'; +import 'package:parabeac_core/design_logic/pb_shared_instance_design_node.dart'; import 'package:parabeac_core/eggs/custom_egg.dart'; import 'package:parabeac_core/eggs/injected_app_bar.dart'; import 'package:parabeac_core/eggs/injected_tab.dart'; @@ -67,15 +69,18 @@ class PBPluginListHelper { /// Returns the PluginNode associated if it exists. PBEgg returnAllowListNodeIfExists(DesignNode node) { // InjectedContainer(null,null)..subsemantic = ''; - for (var key in allowListNames.keys) { - if (node.name.contains(key)) { - return allowListNames[key].generatePluginNode( - Point(node.boundaryRectangle.x, node.boundaryRectangle.y), - Point(node.boundaryRectangle.x + node.boundaryRectangle.width, - node.boundaryRectangle.y + node.boundaryRectangle.height), - node); + if (node is! PBArtboard && node is! PBSharedInstanceDesignNode) { + for (var key in allowListNames.keys) { + if (node.name.contains(key)) { + return allowListNames[key].generatePluginNode( + Point(node.boundaryRectangle.x, node.boundaryRectangle.y), + Point(node.boundaryRectangle.x + node.boundaryRectangle.width, + node.boundaryRectangle.y + node.boundaryRectangle.height), + node); + } } } + return null; } returnDenyListNodeIfExist(SymbolInstance symbolInstance) {} From 1eea96a21f5299bbeca2d38a729deb17c664579a Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 22 Jul 2021 17:20:23 -0600 Subject: [PATCH 249/404] Fixed attribute name --- lib/eggs/custom_egg.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 7beb4b5c..f206cee7 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -40,7 +40,7 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { child.UUID, )..addChild(child); - getAttributeNamed('title').attributeNode = tempNode; + getAttributeNamed('child').attributeNode = tempNode; } @override From 83a9d11c993417d46dc11e1855364f1e395f4ea5 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 22 Jul 2021 18:40:03 -0600 Subject: [PATCH 250/404] REFACTORED our Point class for the one in the dart:math package. --- lib/design_logic/group_node.dart | 6 +-- lib/design_logic/pb_shared_master_node.dart | 2 +- lib/design_logic/rectangle.dart | 2 +- lib/design_logic/text.dart | 2 +- lib/eggs/injected_app_bar.dart | 2 +- lib/eggs/injected_back_arrow.dart | 2 +- lib/eggs/injected_tab.dart | 2 +- lib/eggs/injected_tab_bar.dart | 2 +- .../generators/plugins/pb_plugin_node.dart | 2 +- .../visual-widgets/pb_container_gen.dart | 2 +- .../prototyping/pb_dest_holder.dart | 2 +- .../figma/entities/layers/component.dart | 2 +- lib/input/figma/entities/layers/group.dart | 6 +-- lib/input/figma/entities/layers/line.dart | 2 +- .../figma/entities/layers/rectangle.dart | 2 +- lib/input/figma/entities/layers/slice.dart | 2 +- lib/input/figma/entities/layers/text.dart | 2 +- lib/input/sketch/entities/layers/group.dart | 6 +-- .../sketch/entities/layers/rectangle.dart | 2 +- .../sketch/entities/layers/sketch_text.dart | 2 +- .../sketch/entities/layers/symbol_master.dart | 2 +- .../entities/alignments/flexible.dart | 2 +- .../alignments/injected_positioned.dart | 2 +- .../entities/alignments/padding.dart | 2 +- .../entities/inherited_bitmap.dart | 4 +- .../entities/inherited_circle.dart | 12 ++++- .../entities/inherited_container.dart | 3 +- .../entities/inherited_oval.dart | 3 +- .../entities/inherited_polygon.dart | 3 +- .../entities/inherited_scaffold.dart | 3 +- .../entities/inherited_shape_group.dart | 3 +- .../entities/inherited_shape_path.dart | 3 +- .../entities/inherited_star.dart | 2 +- .../entities/inherited_text.dart | 3 +- .../entities/inherited_triangle.dart | 3 +- .../entities/injected_container.dart | 3 +- .../layouts/rules/axis_comparison_rules.dart | 2 +- .../entities/layouts/rules/handle_flex.dart | 2 +- .../entities/layouts/stack.dart | 2 +- .../entities/pb_deny_list_node.dart | 3 +- .../entities/pb_shared_instance.dart | 2 +- .../entities/pb_shared_master_node.dart | 2 +- .../subclasses/pb_intermediate_node.dart | 34 ++++++++++++- .../pb_layout_intermediate_node.dart | 1 - .../pb_visual_intermediate_node.dart | 4 +- .../helpers/pb_context.dart | 12 +++-- .../helpers/pb_deny_list_helper.dart | 2 +- .../helpers/pb_plugin_list_helper.dart | 2 +- .../helpers/shapes_utils.dart | 2 +- ...b_platform_orientation_linker_service.dart | 2 +- .../pb_symbol_master_params.dart | 2 +- .../value_objects/point.dart | 51 ------------------- 52 files changed, 118 insertions(+), 112 deletions(-) delete mode 100644 lib/interpret_and_optimize/value_objects/point.dart diff --git a/lib/design_logic/group_node.dart b/lib/design_logic/group_node.dart index a6bf0e2e..a5957016 100644 --- a/lib/design_logic/group_node.dart +++ b/lib/design_logic/group_node.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'abstract_design_node_factory.dart'; @@ -116,8 +116,8 @@ class GroupNode implements DesignNodeFactory, DesignNode { @override Future interpretNode(PBContext currentContext) => Future.value(TempGroupLayoutNode(this, currentContext, name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point( + topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), + bottomRightCorner: Point( boundaryRectangle.x + boundaryRectangle.width, boundaryRectangle.y + boundaryRectangle.height))); diff --git a/lib/design_logic/pb_shared_master_node.dart b/lib/design_logic/pb_shared_master_node.dart index d0931d6f..98c32c74 100644 --- a/lib/design_logic/pb_shared_master_node.dart +++ b/lib/design_logic/pb_shared_master_node.dart @@ -7,7 +7,7 @@ import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'abstract_design_node_factory.dart'; diff --git a/lib/design_logic/rectangle.dart b/lib/design_logic/rectangle.dart index 27008f7d..f9ebe2ca 100644 --- a/lib/design_logic/rectangle.dart +++ b/lib/design_logic/rectangle.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_containe import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'abstract_design_node_factory.dart'; import 'color.dart'; diff --git a/lib/design_logic/text.dart b/lib/design_logic/text.dart index 80a24755..f7d447e3 100644 --- a/lib/design_logic/text.dart +++ b/lib/design_logic/text.dart @@ -7,7 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/injected_container import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; import 'abstract_design_node_factory.dart'; diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index e9a325bb..991a5d68 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -6,7 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index 2a6f23f5..dd7487aa 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { @override diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index db17168d..0d86231c 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prot import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 5b4b574d..5d1624ca 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -7,7 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'injected_tab.dart'; diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index abb89aa0..276d5f2d 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -2,7 +2,7 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; abstract class PBEgg extends PBVisualIntermediateNode { /// The allow list semantic name to detect this node. diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index 5bbb7394..11582130 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_hel import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class PBContainerGenerator extends PBGenerator { String color; diff --git a/lib/generation/prototyping/pb_dest_holder.dart b/lib/generation/prototyping/pb_dest_holder.dart index 700b0981..ecc80961 100644 --- a/lib/generation/prototyping/pb_dest_holder.dart +++ b/lib/generation/prototyping/pb_dest_holder.dart @@ -3,7 +3,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class PBDestHolder extends PBIntermediateNode { PrototypeNode pNode; diff --git a/lib/input/figma/entities/layers/component.dart b/lib/input/figma/entities/layers/component.dart index 6bdf0d96..b803f6b2 100644 --- a/lib/input/figma/entities/layers/component.dart +++ b/lib/input/figma/entities/layers/component.dart @@ -12,7 +12,7 @@ import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'component.g.dart'; diff --git a/lib/input/figma/entities/layers/group.dart b/lib/input/figma/entities/layers/group.dart index b16cd6ec..c3dd9b5a 100644 --- a/lib/input/figma/entities/layers/group.dart +++ b/lib/input/figma/entities/layers/group.dart @@ -16,7 +16,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:quick_log/quick_log.dart'; part 'group.g.dart'; @@ -128,8 +128,8 @@ class Group extends FigmaFrame implements AbstractFigmaNodeFactory, Image { this, currentContext, name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point(boundaryRectangle.x + boundaryRectangle.width, + topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), + bottomRightCorner: Point(boundaryRectangle.x + boundaryRectangle.width, boundaryRectangle.y + boundaryRectangle.height), constraints: convertFigmaConstraintToPBDLConstraint(constraints), )); diff --git a/lib/input/figma/entities/layers/line.dart b/lib/input/figma/entities/layers/line.dart index 05e6b280..1dda84b9 100644 --- a/lib/input/figma/entities/layers/line.dart +++ b/lib/input/figma/entities/layers/line.dart @@ -9,7 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'figma_node.dart'; diff --git a/lib/input/figma/entities/layers/rectangle.dart b/lib/input/figma/entities/layers/rectangle.dart index c74999e6..76750558 100644 --- a/lib/input/figma/entities/layers/rectangle.dart +++ b/lib/input/figma/entities/layers/rectangle.dart @@ -14,7 +14,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'figma_node.dart'; diff --git a/lib/input/figma/entities/layers/slice.dart b/lib/input/figma/entities/layers/slice.dart index 03c11a64..b52d0f5b 100644 --- a/lib/input/figma/entities/layers/slice.dart +++ b/lib/input/figma/entities/layers/slice.dart @@ -8,7 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'slice.g.dart'; diff --git a/lib/input/figma/entities/layers/text.dart b/lib/input/figma/entities/layers/text.dart index 59361ceb..ee96c0cc 100644 --- a/lib/input/figma/entities/layers/text.dart +++ b/lib/input/figma/entities/layers/text.dart @@ -14,7 +14,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'figma_node.dart'; diff --git a/lib/input/sketch/entities/layers/group.dart b/lib/input/sketch/entities/layers/group.dart index 2c442381..f432c62d 100644 --- a/lib/input/sketch/entities/layers/group.dart +++ b/lib/input/sketch/entities/layers/group.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'group.g.dart'; @@ -118,8 +118,8 @@ class Group extends AbstractGroupLayer implements SketchNodeFactory { @override Future interpretNode(PBContext currentContext) => Future.value(TempGroupLayoutNode(this, currentContext, name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point( + topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), + bottomRightCorner: Point( boundaryRectangle.x + boundaryRectangle.width, boundaryRectangle.y + boundaryRectangle.height), constraints: diff --git a/lib/input/sketch/entities/layers/rectangle.dart b/lib/input/sketch/entities/layers/rectangle.dart index ac991c9d..54e7408c 100644 --- a/lib/input/sketch/entities/layers/rectangle.dart +++ b/lib/input/sketch/entities/layers/rectangle.dart @@ -12,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_containe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'rectangle.g.dart'; diff --git a/lib/input/sketch/entities/layers/sketch_text.dart b/lib/input/sketch/entities/layers/sketch_text.dart index e0e1430b..f9ecbced 100644 --- a/lib/input/sketch/entities/layers/sketch_text.dart +++ b/lib/input/sketch/entities/layers/sketch_text.dart @@ -12,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; part 'sketch_text.g.dart'; diff --git a/lib/input/sketch/entities/layers/symbol_master.dart b/lib/input/sketch/entities/layers/symbol_master.dart index 85cf6a08..fc444cc1 100644 --- a/lib/input/sketch/entities/layers/symbol_master.dart +++ b/lib/input/sketch/entities/layers/symbol_master.dart @@ -15,7 +15,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_n import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'symbol_master.g.dart'; // title: Symbol Master Layer diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index 575b6ead..a758341e 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -2,7 +2,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_flexible_g import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class Flexible extends PBVisualIntermediateNode { int flex; diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index 00e896a6..d6c672d8 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class InjectedPositioned extends PBIntermediateNode implements PBInjectedIntermediate { diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index 127f0d92..7e262d7e 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class Padding extends PBVisualIntermediateNode { double left, right, top, bottom, screenWidth, screenHeight; diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index 47fbab7e..6079e346 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/design_logic/image.dart'; @@ -10,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +// import 'dart:math'; import 'package:quick_log/quick_log.dart'; class InheritedBitmap extends PBVisualIntermediateNode diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 6ab153e3..b500e658 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; @@ -8,7 +10,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class InheritedCircle extends PBVisualIntermediateNode implements PBInheritedIntermediate { @@ -42,6 +43,13 @@ class InheritedCircle extends PBVisualIntermediateNode @override void alignChild() { + // var padding = Padding('', child.constraints, + // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), + // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), + // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), + // bottom: (child.bottomRightCorner.y - bottomRightCorner.y).abs(), + // topLeftCorner: topLeftCorner, + // bottomRightCorner: bottomRightCorner, var padding = Padding('', child.constraints, left: (child.topLeftCorner.x - topLeftCorner.x).abs(), right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), @@ -52,5 +60,7 @@ class InheritedCircle extends PBVisualIntermediateNode currentContext: currentContext); padding.addChild(child); child = padding; + // padding.addChild(child); + // child = padding; } } diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 6152c373..ee59cc2d 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/design_logic/color.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; @@ -11,7 +13,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class InheritedContainer extends PBVisualIntermediateNode with PBColorMixin diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index 861c67f6..c31b6f51 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -11,7 +13,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:quick_log/quick_log.dart'; class InheritedOval extends PBVisualIntermediateNode diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index b22dd61c..9dfe53cf 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -11,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedPolygon extends PBVisualIntermediateNode implements PBInheritedIntermediate { diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index bfd716b0..73d8f4ed 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/design_logic/color.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/eggs/injected_app_bar.dart'; @@ -12,7 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attr import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + import 'interfaces/pb_inherited_intermediate.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index 2f9039c1..b6801465 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; @@ -11,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedShapeGroup extends PBVisualIntermediateNode implements PBInheritedIntermediate { diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 2340e065..44aafdf8 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; @@ -14,7 +15,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedShapePath extends PBVisualIntermediateNode with PBColorMixin diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index 54443a1c..6173ae2c 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -11,7 +12,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class InheritedStar extends PBVisualIntermediateNode implements PBInheritedIntermediate { diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 8451cf48..84c491fd 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/design_logic/color.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/design_logic/text.dart'; @@ -8,7 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedText extends PBVisualIntermediateNode with PBColorMixin diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 24e43e83..c92cfdcd 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -11,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedTriangle extends PBVisualIntermediateNode implements PBInheritedIntermediate { diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 13e82829..71c40386 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; @@ -9,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InjectedContainer extends PBVisualIntermediateNode implements PBInjectedIntermediate, PrototypeEnable { diff --git a/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart b/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart index 2f5abeb2..832afe6f 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart @@ -1,6 +1,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; ///provides comparison function for UI elements. mixin AxisComparisonRule { diff --git a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart index 51030f20..f95d8782 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/alignments/spacer. import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; /// Calculates the flex of a child relative to its parent diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 9048eca5..b72414f6 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -35,7 +35,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { /// childrend are being populated, and consequently [Stack.resize] is being /// called, then [depth] could be null. [depth] is null when the [PBIntermediateTree] /// has not finished creating and converting PBDL nodes into [PBIntermediateNode]. - if (depth != null && depth <= 2 && depth >= 0) { + if (depth != null && depth <= 1 && depth >= 0) { topLeftCorner = currentContext.canvasTLC; bottomRightCorner = currentContext.canvasBRC; } else { diff --git a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart index 22efa1a1..654aa052 100644 --- a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart +++ b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart @@ -1,7 +1,8 @@ +import 'dart:math'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + /// A node that should not be converted to intermediate. class PBDenyListNode extends PBIntermediateNode { diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index b6201a2e..27f57e17 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_instancesym_gen.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; @@ -10,7 +11,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; /// As some nodes are shared throughout the project, shared instances are pointers to shared master nodes with overridable properties. diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 22e0f4fd..b359e036 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_mastersym_gen.dart'; @@ -11,7 +12,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:quick_log/quick_log.dart'; class PBSharedMasterNode extends PBVisualIntermediateNode diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index e67ed16a..d9adf133 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -8,7 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +// import 'dart:math'; import 'package:quick_log/quick_log.dart'; /// PB’s representation of the intermediate representation for a sketch node. @@ -143,3 +143,35 @@ abstract class PBIntermediateNode extends TraversableNode { childrenStrategy.addChild(this, node); } } +extension PBPointLegacyMethod on Point{ + Point clone(Point point) => Point(point.x, point.y); + + // TODO: This is a temporal fix + // (y.abs() - anotherPoint.y.abs()).abs() < 3 + @override + int compareTo(Point anotherPoint) => + y == anotherPoint.y || (y.abs() - anotherPoint.y.abs()).abs() < 3 + ? x.compareTo(anotherPoint.x) + : y.compareTo(anotherPoint.y); + // @override + // bool operator ==(Object point) { + // if (point is Point) { + // return y == point.y ? x == point.x : y == point.y; + // } + // return false; + // } + + bool operator <(Object point) { + if (point is Point) { + return y == point.y ? x <= point.x : y <= point.y; + } + return false; + } + + bool operator >(Object point) { + if (point is Point) { + return y == point.y ? x >= point.x : y >= point.y; + } + return false; + } +} \ No newline at end of file diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index f5e40f4b..87949488 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -7,7 +7,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:uuid/uuid.dart'; /// This represents a node that should be a Layout; it contains a set of children arranged in a specific manner. It is also responsible for understanding its main axis spacing, and crossAxisAlignment. diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart index 9ff85182..88715198 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart @@ -1,7 +1,9 @@ +import 'dart:math'; + import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +// import 'dart:math'; /// Represents a typical node that the end-user could see, it usually has properties such as size and color. It only contains a single child, unlike PBLayoutIntermediateNode that contains a set of children. /// Superclass: PBIntermediateNode diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 750c9484..8d6dc89b 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_n import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class PBContext { final PBConfiguration configuration; @@ -28,8 +28,8 @@ class PBContext { _screenBRC = screenBottomRightCorner; } - double get originalScreenWidth => Point.dist(_screenTLC, _screenBRC); - double get originaScreenHeight => Point.dist(_screenTLC, _screenBRC, false); + double get originalScreenWidth => _screenBRC.x - _screenTLC.x; + double get originaScreenHeight => _screenBRC.y - _screenTLC.y; /// These values represent the current "focus area" size as it travels down the /// tree. @@ -69,8 +69,10 @@ class PBContext { if (size == 0) { return size; } - return isHorizontal ? size / originalScreenWidth : size / originaScreenHeight; - } + return isHorizontal + ? size / originalScreenWidth + : size / originaScreenHeight; + } } enum SizingValueContext { diff --git a/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart index 22244f5f..f6e88e10 100644 --- a/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart @@ -1,6 +1,6 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_deny_list_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; // Helping understand indirect and direct semantics that should remove a node from a tree. class PBDenyListHelper { diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index d861c1fe..66ac881d 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/input/sketch/entities/layers/symbol_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; /// Helping understand indirect and direct semantics that should remove a node from a tree. diff --git a/lib/interpret_and_optimize/helpers/shapes_utils.dart b/lib/interpret_and_optimize/helpers/shapes_utils.dart index d5241312..3680cb93 100644 --- a/lib/interpret_and_optimize/helpers/shapes_utils.dart +++ b/lib/interpret_and_optimize/helpers/shapes_utils.dart @@ -1,4 +1,4 @@ -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class ShapesComparisonUtils { static bool areXCoordinatesOverlapping( diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index b52611d5..9991edad 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:recase/recase.dart'; class PBPlatformOrientationLinkerService { diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart index 3ff48f41..aa132a78 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; ///TODO: Need another class for elements that generate but are not visuals. diff --git a/lib/interpret_and_optimize/value_objects/point.dart b/lib/interpret_and_optimize/value_objects/point.dart deleted file mode 100644 index 8133b291..00000000 --- a/lib/interpret_and_optimize/value_objects/point.dart +++ /dev/null @@ -1,51 +0,0 @@ -///Geographical point on the canvas. -class Point implements Comparable { - ///absolue positions - final double x, y; - - Point(this.x, this.y); - - @override - String toString() => ' X: $x, Y:$y'; - - Point clone(Point point) => Point(point.x, point.y); - - // TODO: This is a temporal fix - // (y.abs() - anotherPoint.y.abs()).abs() < 3 - @override - int compareTo(Point anotherPoint) => - y == anotherPoint.y || (y.abs() - anotherPoint.y.abs()).abs() < 3 - ? x.compareTo(anotherPoint.x) - : y.compareTo(anotherPoint.y); - @override - bool operator ==(Object point) { - if (point is Point) { - return y == point.y ? x == point.x : y == point.y; - } - return false; - } - - bool operator <(Object point) { - if (point is Point) { - return y == point.y ? x <= point.x : y <= point.y; - } - return false; - } - - bool operator >(Object point) { - if (point is Point) { - return y == point.y ? x >= point.x : y >= point.y; - } - return false; - } - /// calculates the distance given two [Point]s - /// - /// [isXAxis], which default to `true`, is a flag on which axis should - /// the calculation be done. - static double dist(Point TLC, Point BTC, [isXAxis = true]){ - if(TLC == null || BTC == null){ - throw NullThrownError(); - } - return isXAxis ? (BTC.x - TLC.x).abs() : (BTC.y - TLC.y).abs(); - } -} From 092003438ccd06b5e051070a6e51ae5f207289a9 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 22 Jul 2021 18:40:03 -0600 Subject: [PATCH 251/404] REFACTORED our Point class for the one in the dart:math package. --- lib/design_logic/group_node.dart | 6 +-- lib/design_logic/pb_shared_master_node.dart | 2 +- lib/design_logic/rectangle.dart | 2 +- lib/design_logic/text.dart | 2 +- lib/eggs/injected_app_bar.dart | 2 +- lib/eggs/injected_back_arrow.dart | 2 +- lib/eggs/injected_tab.dart | 2 +- lib/eggs/injected_tab_bar.dart | 2 +- .../generators/plugins/pb_plugin_node.dart | 2 +- .../visual-widgets/pb_container_gen.dart | 2 +- .../prototyping/pb_dest_holder.dart | 2 +- .../figma/entities/layers/component.dart | 2 +- lib/input/figma/entities/layers/group.dart | 6 +-- lib/input/figma/entities/layers/line.dart | 2 +- .../figma/entities/layers/rectangle.dart | 2 +- lib/input/figma/entities/layers/slice.dart | 2 +- lib/input/figma/entities/layers/text.dart | 2 +- lib/input/sketch/entities/layers/group.dart | 6 +-- .../sketch/entities/layers/rectangle.dart | 2 +- .../sketch/entities/layers/sketch_text.dart | 2 +- .../sketch/entities/layers/symbol_master.dart | 2 +- .../entities/alignments/flexible.dart | 2 +- .../alignments/injected_positioned.dart | 2 +- .../entities/alignments/padding.dart | 2 +- .../entities/inherited_bitmap.dart | 4 +- .../entities/inherited_circle.dart | 12 ++++- .../entities/inherited_container.dart | 3 +- .../entities/inherited_oval.dart | 3 +- .../entities/inherited_polygon.dart | 3 +- .../entities/inherited_scaffold.dart | 3 +- .../entities/inherited_shape_group.dart | 3 +- .../entities/inherited_shape_path.dart | 3 +- .../entities/inherited_star.dart | 2 +- .../entities/inherited_text.dart | 3 +- .../entities/inherited_triangle.dart | 3 +- .../entities/injected_container.dart | 3 +- .../layouts/rules/axis_comparison_rules.dart | 2 +- .../entities/layouts/rules/handle_flex.dart | 2 +- .../entities/layouts/stack.dart | 2 +- .../entities/pb_deny_list_node.dart | 3 +- .../entities/pb_shared_instance.dart | 2 +- .../entities/pb_shared_master_node.dart | 2 +- .../subclasses/pb_intermediate_node.dart | 26 +++++++++- .../pb_layout_intermediate_node.dart | 1 - .../pb_visual_intermediate_node.dart | 4 +- .../helpers/pb_context.dart | 12 +++-- .../helpers/pb_deny_list_helper.dart | 2 +- .../helpers/pb_plugin_list_helper.dart | 2 +- .../helpers/shapes_utils.dart | 2 +- ...b_platform_orientation_linker_service.dart | 2 +- .../pb_symbol_master_params.dart | 2 +- .../value_objects/point.dart | 51 ------------------- 52 files changed, 110 insertions(+), 112 deletions(-) delete mode 100644 lib/interpret_and_optimize/value_objects/point.dart diff --git a/lib/design_logic/group_node.dart b/lib/design_logic/group_node.dart index a6bf0e2e..a5957016 100644 --- a/lib/design_logic/group_node.dart +++ b/lib/design_logic/group_node.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'abstract_design_node_factory.dart'; @@ -116,8 +116,8 @@ class GroupNode implements DesignNodeFactory, DesignNode { @override Future interpretNode(PBContext currentContext) => Future.value(TempGroupLayoutNode(this, currentContext, name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point( + topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), + bottomRightCorner: Point( boundaryRectangle.x + boundaryRectangle.width, boundaryRectangle.y + boundaryRectangle.height))); diff --git a/lib/design_logic/pb_shared_master_node.dart b/lib/design_logic/pb_shared_master_node.dart index d0931d6f..98c32c74 100644 --- a/lib/design_logic/pb_shared_master_node.dart +++ b/lib/design_logic/pb_shared_master_node.dart @@ -7,7 +7,7 @@ import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'abstract_design_node_factory.dart'; diff --git a/lib/design_logic/rectangle.dart b/lib/design_logic/rectangle.dart index 27008f7d..f9ebe2ca 100644 --- a/lib/design_logic/rectangle.dart +++ b/lib/design_logic/rectangle.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_containe import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'abstract_design_node_factory.dart'; import 'color.dart'; diff --git a/lib/design_logic/text.dart b/lib/design_logic/text.dart index 80a24755..f7d447e3 100644 --- a/lib/design_logic/text.dart +++ b/lib/design_logic/text.dart @@ -7,7 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/injected_container import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; import 'abstract_design_node_factory.dart'; diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index e9a325bb..991a5d68 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -6,7 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index 2a6f23f5..dd7487aa 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { @override diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index db17168d..0d86231c 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prot import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 5b4b574d..5d1624ca 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -7,7 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'injected_tab.dart'; diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index abb89aa0..276d5f2d 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -2,7 +2,7 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; abstract class PBEgg extends PBVisualIntermediateNode { /// The allow list semantic name to detect this node. diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index 5bbb7394..11582130 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_hel import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class PBContainerGenerator extends PBGenerator { String color; diff --git a/lib/generation/prototyping/pb_dest_holder.dart b/lib/generation/prototyping/pb_dest_holder.dart index 700b0981..ecc80961 100644 --- a/lib/generation/prototyping/pb_dest_holder.dart +++ b/lib/generation/prototyping/pb_dest_holder.dart @@ -3,7 +3,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class PBDestHolder extends PBIntermediateNode { PrototypeNode pNode; diff --git a/lib/input/figma/entities/layers/component.dart b/lib/input/figma/entities/layers/component.dart index 6bdf0d96..b803f6b2 100644 --- a/lib/input/figma/entities/layers/component.dart +++ b/lib/input/figma/entities/layers/component.dart @@ -12,7 +12,7 @@ import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'component.g.dart'; diff --git a/lib/input/figma/entities/layers/group.dart b/lib/input/figma/entities/layers/group.dart index b16cd6ec..c3dd9b5a 100644 --- a/lib/input/figma/entities/layers/group.dart +++ b/lib/input/figma/entities/layers/group.dart @@ -16,7 +16,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:quick_log/quick_log.dart'; part 'group.g.dart'; @@ -128,8 +128,8 @@ class Group extends FigmaFrame implements AbstractFigmaNodeFactory, Image { this, currentContext, name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point(boundaryRectangle.x + boundaryRectangle.width, + topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), + bottomRightCorner: Point(boundaryRectangle.x + boundaryRectangle.width, boundaryRectangle.y + boundaryRectangle.height), constraints: convertFigmaConstraintToPBDLConstraint(constraints), )); diff --git a/lib/input/figma/entities/layers/line.dart b/lib/input/figma/entities/layers/line.dart index 05e6b280..1dda84b9 100644 --- a/lib/input/figma/entities/layers/line.dart +++ b/lib/input/figma/entities/layers/line.dart @@ -9,7 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'figma_node.dart'; diff --git a/lib/input/figma/entities/layers/rectangle.dart b/lib/input/figma/entities/layers/rectangle.dart index c74999e6..76750558 100644 --- a/lib/input/figma/entities/layers/rectangle.dart +++ b/lib/input/figma/entities/layers/rectangle.dart @@ -14,7 +14,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'figma_node.dart'; diff --git a/lib/input/figma/entities/layers/slice.dart b/lib/input/figma/entities/layers/slice.dart index 03c11a64..b52d0f5b 100644 --- a/lib/input/figma/entities/layers/slice.dart +++ b/lib/input/figma/entities/layers/slice.dart @@ -8,7 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'slice.g.dart'; diff --git a/lib/input/figma/entities/layers/text.dart b/lib/input/figma/entities/layers/text.dart index 59361ceb..ee96c0cc 100644 --- a/lib/input/figma/entities/layers/text.dart +++ b/lib/input/figma/entities/layers/text.dart @@ -14,7 +14,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'figma_node.dart'; diff --git a/lib/input/sketch/entities/layers/group.dart b/lib/input/sketch/entities/layers/group.dart index 2c442381..f432c62d 100644 --- a/lib/input/sketch/entities/layers/group.dart +++ b/lib/input/sketch/entities/layers/group.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'group.g.dart'; @@ -118,8 +118,8 @@ class Group extends AbstractGroupLayer implements SketchNodeFactory { @override Future interpretNode(PBContext currentContext) => Future.value(TempGroupLayoutNode(this, currentContext, name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point( + topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), + bottomRightCorner: Point( boundaryRectangle.x + boundaryRectangle.width, boundaryRectangle.y + boundaryRectangle.height), constraints: diff --git a/lib/input/sketch/entities/layers/rectangle.dart b/lib/input/sketch/entities/layers/rectangle.dart index ac991c9d..54e7408c 100644 --- a/lib/input/sketch/entities/layers/rectangle.dart +++ b/lib/input/sketch/entities/layers/rectangle.dart @@ -12,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_containe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'rectangle.g.dart'; diff --git a/lib/input/sketch/entities/layers/sketch_text.dart b/lib/input/sketch/entities/layers/sketch_text.dart index e0e1430b..f9ecbced 100644 --- a/lib/input/sketch/entities/layers/sketch_text.dart +++ b/lib/input/sketch/entities/layers/sketch_text.dart @@ -12,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; part 'sketch_text.g.dart'; diff --git a/lib/input/sketch/entities/layers/symbol_master.dart b/lib/input/sketch/entities/layers/symbol_master.dart index 85cf6a08..fc444cc1 100644 --- a/lib/input/sketch/entities/layers/symbol_master.dart +++ b/lib/input/sketch/entities/layers/symbol_master.dart @@ -15,7 +15,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_n import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; part 'symbol_master.g.dart'; // title: Symbol Master Layer diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index 575b6ead..a758341e 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -2,7 +2,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_flexible_g import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class Flexible extends PBVisualIntermediateNode { int flex; diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index 00e896a6..d6c672d8 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class InjectedPositioned extends PBIntermediateNode implements PBInjectedIntermediate { diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index 127f0d92..7e262d7e 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class Padding extends PBVisualIntermediateNode { double left, right, top, bottom, screenWidth, screenHeight; diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index 47fbab7e..6079e346 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/design_logic/image.dart'; @@ -10,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +// import 'dart:math'; import 'package:quick_log/quick_log.dart'; class InheritedBitmap extends PBVisualIntermediateNode diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 6ab153e3..b500e658 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; @@ -8,7 +10,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class InheritedCircle extends PBVisualIntermediateNode implements PBInheritedIntermediate { @@ -42,6 +43,13 @@ class InheritedCircle extends PBVisualIntermediateNode @override void alignChild() { + // var padding = Padding('', child.constraints, + // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), + // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), + // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), + // bottom: (child.bottomRightCorner.y - bottomRightCorner.y).abs(), + // topLeftCorner: topLeftCorner, + // bottomRightCorner: bottomRightCorner, var padding = Padding('', child.constraints, left: (child.topLeftCorner.x - topLeftCorner.x).abs(), right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), @@ -52,5 +60,7 @@ class InheritedCircle extends PBVisualIntermediateNode currentContext: currentContext); padding.addChild(child); child = padding; + // padding.addChild(child); + // child = padding; } } diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 6152c373..ee59cc2d 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/design_logic/color.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; @@ -11,7 +13,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class InheritedContainer extends PBVisualIntermediateNode with PBColorMixin diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index 861c67f6..c31b6f51 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -11,7 +13,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:quick_log/quick_log.dart'; class InheritedOval extends PBVisualIntermediateNode diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index b22dd61c..9dfe53cf 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -11,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedPolygon extends PBVisualIntermediateNode implements PBInheritedIntermediate { diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index bfd716b0..73d8f4ed 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/design_logic/color.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/eggs/injected_app_bar.dart'; @@ -12,7 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attr import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + import 'interfaces/pb_inherited_intermediate.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index 2f9039c1..b6801465 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; @@ -11,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedShapeGroup extends PBVisualIntermediateNode implements PBInheritedIntermediate { diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 2340e065..44aafdf8 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; @@ -14,7 +15,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedShapePath extends PBVisualIntermediateNode with PBColorMixin diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index 54443a1c..6173ae2c 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -11,7 +12,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class InheritedStar extends PBVisualIntermediateNode implements PBInheritedIntermediate { diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 8451cf48..84c491fd 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/design_logic/color.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/design_logic/text.dart'; @@ -8,7 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedText extends PBVisualIntermediateNode with PBColorMixin diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 24e43e83..c92cfdcd 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; @@ -11,7 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InheritedTriangle extends PBVisualIntermediateNode implements PBInheritedIntermediate { diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 13e82829..71c40386 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; @@ -9,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + class InjectedContainer extends PBVisualIntermediateNode implements PBInjectedIntermediate, PrototypeEnable { diff --git a/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart b/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart index 2f5abeb2..832afe6f 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart @@ -1,6 +1,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; ///provides comparison function for UI elements. mixin AxisComparisonRule { diff --git a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart index 51030f20..f95d8782 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/alignments/spacer. import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; /// Calculates the flex of a child relative to its parent diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 9048eca5..b72414f6 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -35,7 +35,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { /// childrend are being populated, and consequently [Stack.resize] is being /// called, then [depth] could be null. [depth] is null when the [PBIntermediateTree] /// has not finished creating and converting PBDL nodes into [PBIntermediateNode]. - if (depth != null && depth <= 2 && depth >= 0) { + if (depth != null && depth <= 1 && depth >= 0) { topLeftCorner = currentContext.canvasTLC; bottomRightCorner = currentContext.canvasBRC; } else { diff --git a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart index 22efa1a1..654aa052 100644 --- a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart +++ b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart @@ -1,7 +1,8 @@ +import 'dart:math'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + /// A node that should not be converted to intermediate. class PBDenyListNode extends PBIntermediateNode { diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index b6201a2e..27f57e17 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_instancesym_gen.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; @@ -10,7 +11,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; /// As some nodes are shared throughout the project, shared instances are pointers to shared master nodes with overridable properties. diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 22e0f4fd..b359e036 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_mastersym_gen.dart'; @@ -11,7 +12,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:quick_log/quick_log.dart'; class PBSharedMasterNode extends PBVisualIntermediateNode diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index e67ed16a..1aac5777 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -8,7 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +// import 'dart:math'; import 'package:quick_log/quick_log.dart'; /// PB’s representation of the intermediate representation for a sketch node. @@ -143,3 +143,27 @@ abstract class PBIntermediateNode extends TraversableNode { childrenStrategy.addChild(this, node); } } +extension PBPointLegacyMethod on Point{ + Point clone(Point point) => Point(point.x, point.y); + + // TODO: This is a temporal fix ----- Not sure why there some sort of safe area for the y-axis?? + // (y.abs() - anotherPoint.y.abs()).abs() < 3 + int compareTo(Point anotherPoint) => + y == anotherPoint.y || (y.abs() - anotherPoint.y.abs()).abs() < 3 + ? x.compareTo(anotherPoint.x) + : y.compareTo(anotherPoint.y); + + bool operator <(Object point) { + if (point is Point) { + return y == point.y ? x <= point.x : y <= point.y; + } + return false; + } + + bool operator >(Object point) { + if (point is Point) { + return y == point.y ? x >= point.x : y >= point.y; + } + return false; + } +} \ No newline at end of file diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index f5e40f4b..87949488 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -7,7 +7,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:uuid/uuid.dart'; /// This represents a node that should be a Layout; it contains a set of children arranged in a specific manner. It is also responsible for understanding its main axis spacing, and crossAxisAlignment. diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart index 9ff85182..88715198 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart @@ -1,7 +1,9 @@ +import 'dart:math'; + import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +// import 'dart:math'; /// Represents a typical node that the end-user could see, it usually has properties such as size and color. It only contains a single child, unlike PBLayoutIntermediateNode that contains a set of children. /// Superclass: PBIntermediateNode diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 750c9484..8d6dc89b 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_n import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class PBContext { final PBConfiguration configuration; @@ -28,8 +28,8 @@ class PBContext { _screenBRC = screenBottomRightCorner; } - double get originalScreenWidth => Point.dist(_screenTLC, _screenBRC); - double get originaScreenHeight => Point.dist(_screenTLC, _screenBRC, false); + double get originalScreenWidth => _screenBRC.x - _screenTLC.x; + double get originaScreenHeight => _screenBRC.y - _screenTLC.y; /// These values represent the current "focus area" size as it travels down the /// tree. @@ -69,8 +69,10 @@ class PBContext { if (size == 0) { return size; } - return isHorizontal ? size / originalScreenWidth : size / originaScreenHeight; - } + return isHorizontal + ? size / originalScreenWidth + : size / originaScreenHeight; + } } enum SizingValueContext { diff --git a/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart index 22244f5f..f6e88e10 100644 --- a/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart @@ -1,6 +1,6 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_deny_list_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; // Helping understand indirect and direct semantics that should remove a node from a tree. class PBDenyListHelper { diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index d861c1fe..66ac881d 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/input/sketch/entities/layers/symbol_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:uuid/uuid.dart'; /// Helping understand indirect and direct semantics that should remove a node from a tree. diff --git a/lib/interpret_and_optimize/helpers/shapes_utils.dart b/lib/interpret_and_optimize/helpers/shapes_utils.dart index d5241312..3680cb93 100644 --- a/lib/interpret_and_optimize/helpers/shapes_utils.dart +++ b/lib/interpret_and_optimize/helpers/shapes_utils.dart @@ -1,4 +1,4 @@ -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; class ShapesComparisonUtils { static bool areXCoordinatesOverlapping( diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index b52611d5..9991edad 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; import 'package:recase/recase.dart'; class PBPlatformOrientationLinkerService { diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart index 3ff48f41..aa132a78 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'dart:math'; ///TODO: Need another class for elements that generate but are not visuals. diff --git a/lib/interpret_and_optimize/value_objects/point.dart b/lib/interpret_and_optimize/value_objects/point.dart deleted file mode 100644 index 8133b291..00000000 --- a/lib/interpret_and_optimize/value_objects/point.dart +++ /dev/null @@ -1,51 +0,0 @@ -///Geographical point on the canvas. -class Point implements Comparable { - ///absolue positions - final double x, y; - - Point(this.x, this.y); - - @override - String toString() => ' X: $x, Y:$y'; - - Point clone(Point point) => Point(point.x, point.y); - - // TODO: This is a temporal fix - // (y.abs() - anotherPoint.y.abs()).abs() < 3 - @override - int compareTo(Point anotherPoint) => - y == anotherPoint.y || (y.abs() - anotherPoint.y.abs()).abs() < 3 - ? x.compareTo(anotherPoint.x) - : y.compareTo(anotherPoint.y); - @override - bool operator ==(Object point) { - if (point is Point) { - return y == point.y ? x == point.x : y == point.y; - } - return false; - } - - bool operator <(Object point) { - if (point is Point) { - return y == point.y ? x <= point.x : y <= point.y; - } - return false; - } - - bool operator >(Object point) { - if (point is Point) { - return y == point.y ? x >= point.x : y >= point.y; - } - return false; - } - /// calculates the distance given two [Point]s - /// - /// [isXAxis], which default to `true`, is a flag on which axis should - /// the calculation be done. - static double dist(Point TLC, Point BTC, [isXAxis = true]){ - if(TLC == null || BTC == null){ - throw NullThrownError(); - } - return isXAxis ? (BTC.x - TLC.x).abs() : (BTC.y - TLC.y).abs(); - } -} From 06b377b56b8bba8ca41c2c04904bfd786cd53dcf Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 22 Jul 2021 18:49:27 -0600 Subject: [PATCH 252/404] REMOVED some reduntant code and moved the [PBContext.getRatioPercentage] method to a conditional statement, where it only happens if we dont have point values --- .../visual-widgets/pb_positioned_gen.dart | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 0cc766cf..e37d9285 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -18,21 +18,7 @@ class PBPositionedGenerator extends PBGenerator { var multStringH = ''; var multStringV = ''; - var valueHolder = PositionedValueHolder( - top: source.valueHolder.top, - bottom: source.valueHolder.bottom, - left: source.valueHolder.left, - right: source.valueHolder.right, - ); - - valueHolder.left = - source.currentContext.getRatioPercentage(source.valueHolder.left, true); - valueHolder.right = - source.currentContext.getRatioPercentage(source.valueHolder.right, true); - valueHolder.top = source.currentContext - .getRatioPercentage(source.valueHolder.top); - valueHolder.bottom = source.currentContext - .getRatioPercentage(source.valueHolder.bottom); + var valueHolder = source.valueHolder; if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { multStringH = 'MediaQuery.of(context).size.width * '; @@ -42,6 +28,17 @@ class PBPositionedGenerator extends PBGenerator { multStringH = 'constraints.maxWidth * '; multStringV = 'constraints.maxHeight * '; } + if (!(generatorContext.sizingContext == SizingValueContext.PointValue)) { + /// [SizingValueContext.PointValue] is the only value in which dont change based on another scale/sizing + valueHolder.left = source.currentContext + .getRatioPercentage(source.valueHolder.left, true); + valueHolder.right = source.currentContext + .getRatioPercentage(source.valueHolder.right, true); + valueHolder.top = + source.currentContext.getRatioPercentage(source.valueHolder.top); + valueHolder.bottom = + source.currentContext.getRatioPercentage(source.valueHolder.bottom); + } buffer.write( 'left: ${_normalizeValue(multStringH, valueHolder.left)}, right: ${_normalizeValue(multStringH, valueHolder.right)},'); @@ -53,10 +50,9 @@ class PBPositionedGenerator extends PBGenerator { buffer.write( 'child: ${source.child.generator.generate(source.child, generatorContext)},'); } catch (e, stackTrace) { - MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); + MainInfo().captureException( + e, + ); log.error(e.toString()); } From c2e0762c0e0e468439e31a92a157024ddaceb6d8 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 22 Jul 2021 21:58:27 -0600 Subject: [PATCH 253/404] REFACTORED Positioned to include the height and width attributes --- lib/generation/generators/pb_generator.dart | 6 ++ .../visual-widgets/pb_positioned_gen.dart | 76 ++++++++++++------- .../alignments/injected_positioned.dart | 21 ++--- .../entities/layouts/stack.dart | 19 +++-- .../subclasses/pb_intermediate_node.dart | 3 + 5 files changed, 77 insertions(+), 48 deletions(-) diff --git a/lib/generation/generators/pb_generator.dart b/lib/generation/generators/pb_generator.dart index 9adac543..2a919ebc 100644 --- a/lib/generation/generators/pb_generator.dart +++ b/lib/generation/generators/pb_generator.dart @@ -2,9 +2,14 @@ import 'package:parabeac_core/generation/generators/value_objects/template_strat import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:quick_log/quick_log.dart'; abstract class PBGenerator { final String OBJECTID = 'UUID'; + static String MEDIAQUERY_HORIZONTAL_BOILERPLATE = 'MediaQuery.of(context).size.width'; + static String MEDIAQUERY_VERTICAL_BOILERPLATE = 'MediaQuery.of(context).size.height'; + + Logger logger; ///The [TemplateStrategy] that is going to be used to generate the boilerplate code around the node. /// @@ -14,6 +19,7 @@ abstract class PBGenerator { PBGenerator({TemplateStrategy strategy}) { templateStrategy = strategy; templateStrategy ??= InlineTemplateStrategy(); + logger = Logger(runtimeType.toString()); } String generate(PBIntermediateNode source, PBContext context); diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index e37d9285..36ecb540 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -3,11 +3,17 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:quick_log/quick_log.dart'; +import 'package:tuple/tuple.dart'; class PBPositionedGenerator extends PBGenerator { - PBPositionedGenerator() : super(); - var log = Logger('Positioned Generator'); + /// The Flutter Position class allows it to override the `height` and the + /// `width` attribute of its `child` to affect the constrains in the y and x axis repectively. + /// The Positioned class has to decide if it would have to override the `top`/`bottom` and `left`/`right`, or + /// by [overrideChildDim] being `true`, the Positioned would use `top`/`height` and `left`/`width`. + /// Reference: https://api.flutter.dev/flutter/widgets/Positioned-class.html + bool overrideChildDim = false; + + PBPositionedGenerator({this.overrideChildDim = false}) : super(); @override String generate(PBIntermediateNode source, PBContext generatorContext) { @@ -15,45 +21,43 @@ class PBPositionedGenerator extends PBGenerator { var buffer = StringBuffer(); buffer.write('Positioned('); - var multStringH = ''; - var multStringV = ''; + var boilerplate = _getBoilerplate(generatorContext.sizingContext); + var xAxisBoilerplate = boilerplate.item1; + var yAxisBoilerplate = boilerplate.item2; var valueHolder = source.valueHolder; - if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { - multStringH = 'MediaQuery.of(context).size.width * '; - multStringV = 'MediaQuery.of(context).size.height *'; - } else if (generatorContext.sizingContext == - SizingValueContext.LayoutBuilderValue) { - multStringH = 'constraints.maxWidth * '; - multStringV = 'constraints.maxHeight * '; - } if (!(generatorContext.sizingContext == SizingValueContext.PointValue)) { /// [SizingValueContext.PointValue] is the only value in which dont change based on another scale/sizing - valueHolder.left = source.currentContext - .getRatioPercentage(source.valueHolder.left, true); - valueHolder.right = source.currentContext - .getRatioPercentage(source.valueHolder.right, true); - valueHolder.top = - source.currentContext.getRatioPercentage(source.valueHolder.top); - valueHolder.bottom = - source.currentContext.getRatioPercentage(source.valueHolder.bottom); - } + var ratio = source.currentContext.getRatioPercentage; + valueHolder.left = ratio(source.valueHolder.left, true); + valueHolder.right = ratio(source.valueHolder.right, true); + valueHolder.top = ratio(source.valueHolder.top); + valueHolder.bottom = ratio(source.valueHolder.bottom); + + valueHolder.height = ratio(source.height); + valueHolder.width = ratio(source.width, true); + } buffer.write( - 'left: ${_normalizeValue(multStringH, valueHolder.left)}, right: ${_normalizeValue(multStringH, valueHolder.right)},'); - buffer.write( - 'top: ${_normalizeValue(multStringV, valueHolder.top)}, bottom: ${_normalizeValue(multStringV, valueHolder.bottom)},'); + 'left: ${_normalizeValue(xAxisBoilerplate, valueHolder.left)}, top: ${_normalizeValue(yAxisBoilerplate, valueHolder.top)},'); + if (overrideChildDim) { + buffer.write( + 'width: ${_normalizeValue(xAxisBoilerplate, valueHolder.width)}, height: ${_normalizeValue(yAxisBoilerplate, valueHolder.height)},'); + } else { + buffer.write( + 'right: ${_normalizeValue(xAxisBoilerplate, valueHolder.right)}, bottom: ${_normalizeValue(yAxisBoilerplate, valueHolder.bottom)},'); + } try { source.child.currentContext = source.currentContext; buffer.write( 'child: ${source.child.generator.generate(source.child, generatorContext)},'); - } catch (e, stackTrace) { + } catch (e) { + logger.error(e.toString()); MainInfo().captureException( e, ); - log.error(e.toString()); } buffer.write(')'); @@ -61,6 +65,19 @@ class PBPositionedGenerator extends PBGenerator { } } + /// Getting the boilerplate needed to fill in the generation depending on the [sizingValueContext]. + Tuple2 _getBoilerplate( + SizingValueContext sizingValueContext) { + if (sizingValueContext == SizingValueContext.ScaleValue) { + return Tuple2('${PBGenerator.MEDIAQUERY_HORIZONTAL_BOILERPLATE} * ', + '${PBGenerator.MEDIAQUERY_VERTICAL_BOILERPLATE} *'); + } + if (sizingValueContext == SizingValueContext.LayoutBuilderValue) { + return Tuple2('constraints.maxWidth * ', 'constraints.maxHeight * '); + } + return Tuple2('', ''); + } + /// Going to return the value without the [preValueStatement] if the [value] /// is equal to `0`. /// @@ -70,9 +87,10 @@ class PBPositionedGenerator extends PBGenerator { /// ``` /// Where it should be `0`. String _normalizeValue(String preValueStatement, double value) { - if (value == 0) { + var n = double.parse(value.toStringAsFixed(3)); + if (n == 0) { return '0'; } - return '$preValueStatement${value.toStringAsFixed(3)}'; + return '$preValueStatement$n'; } } diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index d6c672d8..85e3ddc2 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -8,11 +8,6 @@ import 'dart:math'; class InjectedPositioned extends PBIntermediateNode implements PBInjectedIntermediate { - @override - PBContext currentContext; - - @override - final String UUID; final PositionedValueHolder valueHolder; @@ -20,13 +15,16 @@ class InjectedPositioned extends PBIntermediateNode ChildrenStrategy childrenStrategy = OneChildStrategy('child'); InjectedPositioned( - this.UUID, { + String UUID, + Point tlc, + Point brc, + { this.valueHolder, - this.currentContext, + PBContext currentContext, PBIntermediateConstraints constraints, - }) : super(Point(0, 0), Point(0, 0), UUID, '', + }) : super(tlc ?? Point(0, 0), brc ?? Point(0, 0), UUID, '', currentContext: currentContext, constraints: constraints) { - generator = PBPositionedGenerator(); + generator = PBPositionedGenerator(overrideChildDim: true); } } @@ -38,11 +36,16 @@ class PositionedValueHolder { double left; double right; + double height; + double width; + PositionedValueHolder({ this.top, this.bottom, this.left, this.right, + this.height, + this.width }) { top ??= 0; bottom ??= 0; diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index b72414f6..d9ed9b38 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -63,13 +63,15 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { left = child.topLeftCorner.x - topLeftCorner.x; right = bottomRightCorner.x - child.bottomRightCorner.x; - alignedChildren.add(InjectedPositioned(Uuid().v4(), + alignedChildren.add(InjectedPositioned( + Uuid().v4(), child.topLeftCorner, child.bottomRightCorner, valueHolder: PositionedValueHolder( - top: top, - bottom: bottom, - left: left, - right: right, - ), + top: top, + bottom: bottom, + left: left, + right: right, + height: child.height, + width: child.width), currentContext: currentContext, constraints: child.constraints) ..addChild(child)); @@ -81,10 +83,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { /// The width of this stack must be the full width of the Scaffold or Artboard. As discussed, at some point we can change this but for now, this makes the most sense. - var stack = PBIntermediateStackLayout( - currentContext, - name: name - ); + var stack = PBIntermediateStackLayout(currentContext, name: name); stack.prototypeNode = prototypeNode; children.forEach((child) => stack.addChild(child)); return stack; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 1aac5777..12e01476 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -57,6 +57,9 @@ abstract class PBIntermediateNode extends TraversableNode { Point topLeftCorner; Point bottomRightCorner; + + double get width => bottomRightCorner.x - topLeftCorner.x; + double get height => bottomRightCorner.y - topLeftCorner.y; PBContext currentContext; From 5265b9ce423b2efa59faa62719c3247327f16e9f Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 22 Jul 2021 21:59:32 -0600 Subject: [PATCH 254/404] WIP added the ability to turn off/on scaling from the configuration file --- lib/configurations/configurations.json | 3 ++- lib/generation/generators/layouts/pb_scaffold_gen.dart | 9 +++++++-- lib/interpret_and_optimize/helpers/pb_configuration.dart | 5 ++++- .../helpers/pb_configuration.g.dart | 2 ++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index 39805d2b..e2a71acf 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -12,5 +12,6 @@ "mobile": 360, "tablet": 600, "desktop": 1280 - } + }, + "scaling": true } \ No newline at end of file diff --git a/lib/generation/generators/layouts/pb_scaffold_gen.dart b/lib/generation/generators/layouts/pb_scaffold_gen.dart index cf672ca8..dafd0e50 100644 --- a/lib/generation/generators/layouts/pb_scaffold_gen.dart +++ b/lib/generation/generators/layouts/pb_scaffold_gen.dart @@ -10,7 +10,9 @@ class PBScaffoldGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext generatorContext) { - generatorContext.sizingContext = SizingValueContext.ScaleValue; + generatorContext.sizingContext = generatorContext.configuration.scaling + ? SizingValueContext.ScaleValue + : SizingValueContext.PointValue; var appBar = source.getAttributeNamed('appBar')?.attributeNode; var body = source.getAttributeNamed('body')?.attributeNode; var bottomNavBar = @@ -39,7 +41,10 @@ class PBScaffoldGenerator extends PBGenerator { } if (body != null) { - generatorContext.sizingContext = SizingValueContext.ScaleValue; + generatorContext.sizingContext = generatorContext.configuration.scaling + ? SizingValueContext.ScaleValue + : SizingValueContext.PointValue; + // hack to pass screen width and height to the child buffer.write('body: '); // generatorContext.sizingContext = SizingValueContext.ScaleValue; diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.dart b/lib/interpret_and_optimize/helpers/pb_configuration.dart index f5413dad..dcfeada1 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.dart @@ -31,6 +31,9 @@ class PBConfiguration { @JsonKey(defaultValue: 'Material') final String widgetStyle; + @JsonKey(defaultValue: true) + final bool scaling; + @JsonKey(defaultValue: 'Stateless') final String widgetType; @@ -47,7 +50,7 @@ class PBConfiguration { final Map breakpoints; PBConfiguration(this.widgetStyle, this.widgetType, this.widgetSpacing, - this.stateManagement, this.layoutPrecedence, this.breakpoints); + this.stateManagement, this.layoutPrecedence, this.breakpoints, this.scaling); /// Converting the [json] into a [PBConfiguration] object. /// diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart index 237c9a53..54c70319 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart @@ -15,12 +15,14 @@ PBConfiguration _$PBConfigurationFromJson(Map json) { (json['layoutPrecedence'] as List)?.map((e) => e as String)?.toList() ?? ['column', 'row', 'stack'], json['breakpoints'] as Map, + json['scaling'] as bool ?? true, ); } Map _$PBConfigurationToJson(PBConfiguration instance) => { 'widgetStyle': instance.widgetStyle, + 'scaling': instance.scaling, 'widgetType': instance.widgetType, 'widgetSpacing': instance.widgetSpacing, 'state-management': instance.stateManagement, From 1d5df0115a017f51beec1a2f006ff6ef84759bde Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 23 Jul 2021 14:18:18 -0600 Subject: [PATCH 255/404] Removed alignChild from custom egg --- lib/eggs/custom_egg.dart | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index f206cee7..5bc8b531 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -33,14 +33,7 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { @override void alignChild() { - var tempNode = InjectedContainer( - child.bottomRightCorner, - child.topLeftCorner, - child.name, - child.UUID, - )..addChild(child); - - getAttributeNamed('child').attributeNode = tempNode; + // Don't do anything } @override From 1982c88f4b0b1d3bedaca86544d195aba9ddf2bd Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 23 Jul 2021 22:34:04 -0600 Subject: [PATCH 256/404] WIP REMOVED padding, REMOVED constrains, and some REFACTORS to Positioned --- lib/configurations/configurations.json | 2 +- .../attribute-helper/pb_size_helper.dart | 4 +-- .../visual-widgets/pb_positioned_gen.dart | 26 +++++++-------- .../figma/entities/style/figma_fill.g.dart | 3 +- .../sketch/entities/layers/sketch_text.g.dart | 2 +- .../alignments/injected_positioned.dart | 8 ++--- .../entities/inherited_circle.dart | 11 +------ .../entities/inherited_container.dart | 32 +++++++++---------- .../entities/inherited_scaffold.dart | 20 ++++++------ .../entities/injected_container.dart | 20 ++++++------ .../entities/layouts/stack.dart | 4 +-- .../entities/pb_shared_instance.dart | 22 ++++++------- .../subclasses/pb_intermediate_node.dart | 6 ++-- .../helpers/pb_context.dart | 2 +- 14 files changed, 77 insertions(+), 85 deletions(-) diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index e2a71acf..c153b392 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -13,5 +13,5 @@ "tablet": 600, "desktop": 1280 }, - "scaling": true + "scaling": true } \ No newline at end of file diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index 5b14d47a..00b48a6d 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -52,8 +52,8 @@ class PBSizeHelper extends PBAttributesHelper { ? body['width'].toStringAsFixed(3) : 'MediaQuery.of(context).size.width * ${relativeWidth.toStringAsFixed(3)}'; - buffer.write( - 'constraints: BoxConstraints(maxHeight: ${height}, maxWidth: ${width}),'); + // buffer.write( + // 'constraints: BoxConstraints(maxHeight: ${height}, maxWidth: ${width}),'); } else if (generatorContext.sizingContext == SizingValueContext.LayoutBuilderValue) { buffer.write( diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 36ecb540..8129f902 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -18,8 +18,7 @@ class PBPositionedGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is InjectedPositioned) { - var buffer = StringBuffer(); - buffer.write('Positioned('); + var buffer = StringBuffer('Positioned('); var boilerplate = _getBoilerplate(generatorContext.sizingContext); var xAxisBoilerplate = boilerplate.item1; @@ -31,16 +30,17 @@ class PBPositionedGenerator extends PBGenerator { /// [SizingValueContext.PointValue] is the only value in which dont change based on another scale/sizing var ratio = source.currentContext.getRatioPercentage; - valueHolder.left = ratio(source.valueHolder.left, true); - valueHolder.right = ratio(source.valueHolder.right, true); - valueHolder.top = ratio(source.valueHolder.top); - valueHolder.bottom = ratio(source.valueHolder.bottom); + valueHolder.left = ratio(source.valueHolder.left, isHorizontal: true); + valueHolder.right = ratio(source.valueHolder.right, isHorizontal: true); + valueHolder.top = ratio(source.valueHolder.top, isHorizontal: false); + valueHolder.bottom = ratio(source.valueHolder.bottom, isHorizontal: false); - valueHolder.height = ratio(source.height); - valueHolder.width = ratio(source.width, true); + valueHolder.height = ratio(source.height, isHorizontal: false); + valueHolder.width = ratio(source.width, isHorizontal: true); } + try { buffer.write( - 'left: ${_normalizeValue(xAxisBoilerplate, valueHolder.left)}, top: ${_normalizeValue(yAxisBoilerplate, valueHolder.top)},'); + 'left: ${_normalizeValue(xAxisBoilerplate, valueHolder.left)}, top: ${valueHolder.top},'); if (overrideChildDim) { buffer.write( 'width: ${_normalizeValue(xAxisBoilerplate, valueHolder.width)}, height: ${_normalizeValue(yAxisBoilerplate, valueHolder.height)},'); @@ -49,7 +49,7 @@ class PBPositionedGenerator extends PBGenerator { 'right: ${_normalizeValue(xAxisBoilerplate, valueHolder.right)}, bottom: ${_normalizeValue(yAxisBoilerplate, valueHolder.bottom)},'); } - try { + source.child.currentContext = source.currentContext; buffer.write( 'child: ${source.child.generator.generate(source.child, generatorContext)},'); @@ -70,7 +70,7 @@ class PBPositionedGenerator extends PBGenerator { SizingValueContext sizingValueContext) { if (sizingValueContext == SizingValueContext.ScaleValue) { return Tuple2('${PBGenerator.MEDIAQUERY_HORIZONTAL_BOILERPLATE} * ', - '${PBGenerator.MEDIAQUERY_VERTICAL_BOILERPLATE} *'); + '${PBGenerator.MEDIAQUERY_VERTICAL_BOILERPLATE} * '); } if (sizingValueContext == SizingValueContext.LayoutBuilderValue) { return Tuple2('constraints.maxWidth * ', 'constraints.maxHeight * '); @@ -88,9 +88,9 @@ class PBPositionedGenerator extends PBGenerator { /// Where it should be `0`. String _normalizeValue(String preValueStatement, double value) { var n = double.parse(value.toStringAsFixed(3)); - if (n == 0) { + if (value == 0) { return '0'; } - return '$preValueStatement$n'; + return '$preValueStatement${value.toStringAsFixed(3)}'; } } diff --git a/lib/input/figma/entities/style/figma_fill.g.dart b/lib/input/figma/entities/style/figma_fill.g.dart index 43f47068..1a7681b9 100644 --- a/lib/input/figma/entities/style/figma_fill.g.dart +++ b/lib/input/figma/entities/style/figma_fill.g.dart @@ -12,10 +12,11 @@ FigmaFill _$FigmaFillFromJson(Map json) { ? null : FigmaColor.fromJson(json['color'] as Map), json['isEnabled'] as bool, - ); + )..fillType = json['fillType'] as int; } Map _$FigmaFillToJson(FigmaFill instance) => { 'color': instance.color, + 'fillType': instance.fillType, 'isEnabled': instance.isEnabled, }; diff --git a/lib/input/sketch/entities/layers/sketch_text.g.dart b/lib/input/sketch/entities/layers/sketch_text.g.dart index 225a7961..6716475f 100644 --- a/lib/input/sketch/entities/layers/sketch_text.g.dart +++ b/lib/input/sketch/entities/layers/sketch_text.g.dart @@ -25,7 +25,7 @@ SketchText _$SketchTextFromJson(Map json) { layerListExpandedType: json['layerListExpandedType'], name: json['name'] as String, nameIsFixed: json['nameIsFixed'] as bool, - resizingConstraint: json['resizingConstraint'], + resizingConstraint: json['resizingConstraint'] as int, resizingType: json['resizingType'], rotation: (json['rotation'] as num)?.toDouble(), sharedStyleID: json['sharedStyleID'], diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index 85e3ddc2..e70365ef 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -47,9 +47,9 @@ class PositionedValueHolder { this.height, this.width }) { - top ??= 0; - bottom ??= 0; - left ??= 0; - right ??= 0; + // top ??= 0; + // bottom ??= 0; + // left ??= 0; + // right ??= 0; } } diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index b500e658..485b33b1 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -50,16 +50,7 @@ class InheritedCircle extends PBVisualIntermediateNode // bottom: (child.bottomRightCorner.y - bottomRightCorner.y).abs(), // topLeftCorner: topLeftCorner, // bottomRightCorner: bottomRightCorner, - var padding = Padding('', child.constraints, - left: (child.topLeftCorner.x - topLeftCorner.x).abs(), - right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), - top: (child.topLeftCorner.y - topLeftCorner.y).abs(), - bottom: (child.bottomRightCorner.y - bottomRightCorner.y).abs(), - topLeftCorner: topLeftCorner, - bottomRightCorner: bottomRightCorner, - currentContext: currentContext); - padding.addChild(child); - child = padding; + // currentContext: currentContext); // padding.addChild(child); // child = padding; } diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index ee59cc2d..e103da3e 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -74,22 +74,22 @@ class InheritedContainer extends PBVisualIntermediateNode if (child != null) { /// Refactor to child.constraints != null if (child is! InheritedText) { - var left = (child.topLeftCorner.x - topLeftCorner.x).abs() ?? 0.0; - var right = - (bottomRightCorner.x - child.bottomRightCorner.x).abs() ?? 0.0; - var top = (child.topLeftCorner.y - topLeftCorner.y).abs() ?? 0.0; - var bottom = - (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0; - var padding = Padding('', child.constraints, - left: left, - right: right, - top: top, - bottom: bottom, - topLeftCorner: topLeftCorner, - bottomRightCorner: bottomRightCorner, - currentContext: currentContext); - padding.addChild(child); - child = padding; + // var left = (child.topLeftCorner.x - topLeftCorner.x).abs() ?? 0.0; + // var right = + // (bottomRightCorner.x - child.bottomRightCorner.x).abs() ?? 0.0; + // var top = (child.topLeftCorner.y - topLeftCorner.y).abs() ?? 0.0; + // var bottom = + // (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0; + // var padding = Padding('', child.constraints, + // left: left, + // right: right, + // top: top, + // bottom: bottom, + // topLeftCorner: topLeftCorner, + // bottomRightCorner: bottomRightCorner, + // currentContext: currentContext); + // padding.addChild(child); + // child = padding; } } } diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 73d8f4ed..5ac5ea7e 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -130,16 +130,16 @@ class InheritedScaffold extends PBVisualIntermediateNode @override void alignChild() { if (child != null) { - var padding = Padding('', child.constraints, - left: (child.topLeftCorner.x - topLeftCorner.x).abs(), - right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), - top: (child.topLeftCorner.y - topLeftCorner.y).abs(), - bottom: (bottomRightCorner.y - child.bottomRightCorner.y).abs(), - topLeftCorner: topLeftCorner, - bottomRightCorner: bottomRightCorner, - currentContext: currentContext); - padding.addChild(child); - child = padding; + // var padding = Padding('', child.constraints, + // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), + // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), + // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), + // bottom: (bottomRightCorner.y - child.bottomRightCorner.y).abs(), + // topLeftCorner: topLeftCorner, + // bottomRightCorner: bottomRightCorner, + // currentContext: currentContext); + // padding.addChild(child); + // child = padding; } } } diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 71c40386..ab95a808 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -42,15 +42,15 @@ class InjectedContainer extends PBVisualIntermediateNode @override void alignChild() { /// Add Padding that takes into account pinning (hard values). - var padding = Padding('', child.constraints, - left: (child.topLeftCorner.x - topLeftCorner.x).abs(), - right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), - top: (child.topLeftCorner.y - topLeftCorner.y).abs(), - bottom: (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0, - topLeftCorner: topLeftCorner, - bottomRightCorner: bottomRightCorner, - currentContext: currentContext); - padding.child = child; - child = padding; + // var padding = Padding('', child.constraints, + // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), + // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), + // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), + // bottom: (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0, + // topLeftCorner: topLeftCorner, + // bottomRightCorner: bottomRightCorner, + // currentContext: currentContext); + // padding.child = child; + // child = padding; } } diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index d9ed9b38..d8a55f3c 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -35,7 +35,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { /// childrend are being populated, and consequently [Stack.resize] is being /// called, then [depth] could be null. [depth] is null when the [PBIntermediateTree] /// has not finished creating and converting PBDL nodes into [PBIntermediateNode]. - if (depth != null && depth <= 1 && depth >= 0) { + if (depth != null && depth <= 2 && depth >= 0) { topLeftCorner = currentContext.canvasTLC; bottomRightCorner = currentContext.canvasBRC; } else { @@ -64,7 +64,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { right = bottomRightCorner.x - child.bottomRightCorner.x; alignedChildren.add(InjectedPositioned( - Uuid().v4(), child.topLeftCorner, child.bottomRightCorner, + Uuid().v4(), child.topLeftCorner.clone(), child.bottomRightCorner.clone(), valueHolder: PositionedValueHolder( top: top, bottom: bottom, diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 27f57e17..c498fc20 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -80,17 +80,17 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @override void alignChild() { if (child != null) { - var padding = Padding('', child.constraints, - left: (child.topLeftCorner.x - topLeftCorner.x).abs(), - right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), - top: (child.topLeftCorner.y - topLeftCorner.y).abs(), - bottom: - (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0, - topLeftCorner: topLeftCorner, - bottomRightCorner: bottomRightCorner, - currentContext: currentContext); - padding.addChild(child); - child = padding; + // var padding = Padding('', child.constraints, + // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), + // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), + // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), + // bottom: + // (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0, + // topLeftCorner: topLeftCorner, + // bottomRightCorner: bottomRightCorner, + // currentContext: currentContext); + // padding.addChild(child); + // child = padding; } } } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 12e01476..26446a2f 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -58,8 +58,8 @@ abstract class PBIntermediateNode extends TraversableNode { Point topLeftCorner; Point bottomRightCorner; - double get width => bottomRightCorner.x - topLeftCorner.x; - double get height => bottomRightCorner.y - topLeftCorner.y; + double get width => (bottomRightCorner.x - topLeftCorner.x).toDouble(); + double get height => (bottomRightCorner.y - topLeftCorner.y).toDouble(); PBContext currentContext; @@ -147,7 +147,7 @@ abstract class PBIntermediateNode extends TraversableNode { } } extension PBPointLegacyMethod on Point{ - Point clone(Point point) => Point(point.x, point.y); + Point clone() => Point(x, y); // TODO: This is a temporal fix ----- Not sure why there some sort of safe area for the y-axis?? // (y.abs() - anotherPoint.y.abs()).abs() < 3 diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 8d6dc89b..9e2b228a 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -65,7 +65,7 @@ class PBContext { /// /// [isHorizontal] (default value is `false`) /// represents if the ratio should be the Horizontal one or the Vertical one. - double getRatioPercentage(double size, [bool isHorizontal = false]) { + double getRatioPercentage(double size, {bool isHorizontal = false}) { if (size == 0) { return size; } From ec4bfbab9eda542678052bdd7ff4a273896e2c46 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 23 Jul 2021 23:02:29 -0600 Subject: [PATCH 257/404] FIX the wrong values for positioned widget (top, right, bottom, and left), the ratio function was being applyed multiple times on the values because of the multiple runs the generation phase has. --- .../visual-widgets/pb_positioned_gen.dart | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 8129f902..b828046a 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -24,7 +24,19 @@ class PBPositionedGenerator extends PBGenerator { var xAxisBoilerplate = boilerplate.item1; var yAxisBoilerplate = boilerplate.item2; - var valueHolder = source.valueHolder; + /// Since the generation phase is going to run multiple times, we are going to have to + /// create a copy/clone of the [PositionedValueHolder] instead of assigning the values + /// directly to the [source.valueHolder]. This would causse the [source.valueHolder.getRatioPercentage] + /// to be applyed to ratios determine in a previoud generation phase run. + /// This is going to be the case until we find a more suitable solution for the generation + /// phase overall. + var valueHolder = PositionedValueHolder( + top: source.valueHolder.top, + bottom: source.valueHolder.bottom, + left: source.valueHolder.left, + right: source.valueHolder.right, + width: source.valueHolder.width, + height: source.valueHolder.height); if (!(generatorContext.sizingContext == SizingValueContext.PointValue)) { /// [SizingValueContext.PointValue] is the only value in which dont change based on another scale/sizing @@ -33,23 +45,23 @@ class PBPositionedGenerator extends PBGenerator { valueHolder.left = ratio(source.valueHolder.left, isHorizontal: true); valueHolder.right = ratio(source.valueHolder.right, isHorizontal: true); valueHolder.top = ratio(source.valueHolder.top, isHorizontal: false); - valueHolder.bottom = ratio(source.valueHolder.bottom, isHorizontal: false); + valueHolder.bottom = + ratio(source.valueHolder.bottom, isHorizontal: false); valueHolder.height = ratio(source.height, isHorizontal: false); valueHolder.width = ratio(source.width, isHorizontal: true); } try { - buffer.write( - 'left: ${_normalizeValue(xAxisBoilerplate, valueHolder.left)}, top: ${valueHolder.top},'); - if (overrideChildDim) { buffer.write( - 'width: ${_normalizeValue(xAxisBoilerplate, valueHolder.width)}, height: ${_normalizeValue(yAxisBoilerplate, valueHolder.height)},'); - } else { - buffer.write( - 'right: ${_normalizeValue(xAxisBoilerplate, valueHolder.right)}, bottom: ${_normalizeValue(yAxisBoilerplate, valueHolder.bottom)},'); - } + 'left: ${_normalizeValue(xAxisBoilerplate, valueHolder.left)}, top: ${_normalizeValue(yAxisBoilerplate, valueHolder.top)},'); + if (overrideChildDim) { + buffer.write( + 'width: ${_normalizeValue(xAxisBoilerplate, valueHolder.width)}, height: ${_normalizeValue(yAxisBoilerplate, valueHolder.height)},'); + } else { + buffer.write( + 'right: ${_normalizeValue(xAxisBoilerplate, valueHolder.right)}, bottom: ${_normalizeValue(yAxisBoilerplate, valueHolder.bottom)},'); + } - source.child.currentContext = source.currentContext; buffer.write( 'child: ${source.child.generator.generate(source.child, generatorContext)},'); @@ -88,9 +100,9 @@ class PBPositionedGenerator extends PBGenerator { /// Where it should be `0`. String _normalizeValue(String preValueStatement, double value) { var n = double.parse(value.toStringAsFixed(3)); - if (value == 0) { + if (n == 0) { return '0'; } - return '$preValueStatement${value.toStringAsFixed(3)}'; + return '$preValueStatement$n'; } } From 0b368fc5ee2dfecb29bde47c88f56a613aa5b982 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 23 Jul 2021 23:59:13 -0600 Subject: [PATCH 258/404] WIP ADDED the PositionAttribute private class that helps us identify if a particular attribute should be constant or using media query. REFACTORED some of the methods and logic in the Position generator to match the PositionAttribute class. --- .../visual-widgets/pb_positioned_gen.dart | 119 +++++++++++++++--- .../entities/subclasses/pbdl_constraints.dart | 5 + 2 files changed, 106 insertions(+), 18 deletions(-) diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index b828046a..5737e3e3 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:tuple/tuple.dart'; @@ -38,29 +39,41 @@ class PBPositionedGenerator extends PBGenerator { width: source.valueHolder.width, height: source.valueHolder.height); + var positionalAtt = _getPositionalAtt(valueHolder, source.constraints); + if (!(generatorContext.sizingContext == SizingValueContext.PointValue)) { /// [SizingValueContext.PointValue] is the only value in which dont change based on another scale/sizing var ratio = source.currentContext.getRatioPercentage; - valueHolder.left = ratio(source.valueHolder.left, isHorizontal: true); - valueHolder.right = ratio(source.valueHolder.right, isHorizontal: true); - valueHolder.top = ratio(source.valueHolder.top, isHorizontal: false); - valueHolder.bottom = - ratio(source.valueHolder.bottom, isHorizontal: false); - - valueHolder.height = ratio(source.height, isHorizontal: false); - valueHolder.width = ratio(source.width, isHorizontal: true); + for (var attribute in positionalAtt) { + if (!attribute.remainPointValue) { + attribute.value = + ratio(attribute.value, isHorizontal: attribute.isXAxis); + } + } + // valueHolder.left = ratio(source.valueHolder.left, isHorizontal: true); + // valueHolder.right = ratio(source.valueHolder.right, isHorizontal: true); + // valueHolder.top = ratio(source.valueHolder.top, isHorizontal: false); + // valueHolder.bottom = + // ratio(source.valueHolder.bottom, isHorizontal: false); + + // valueHolder.height = ratio(source.height, isHorizontal: false); + // valueHolder.width = ratio(source.width, isHorizontal: true); } try { - buffer.write( - 'left: ${_normalizeValue(xAxisBoilerplate, valueHolder.left)}, top: ${_normalizeValue(yAxisBoilerplate, valueHolder.top)},'); - if (overrideChildDim) { + for (var attribute in positionalAtt) { buffer.write( - 'width: ${_normalizeValue(xAxisBoilerplate, valueHolder.width)}, height: ${_normalizeValue(yAxisBoilerplate, valueHolder.height)},'); - } else { - buffer.write( - 'right: ${_normalizeValue(xAxisBoilerplate, valueHolder.right)}, bottom: ${_normalizeValue(yAxisBoilerplate, valueHolder.bottom)},'); + '${attribute.attributeName}: ${_normalizeValue(attribute.isXAxis ? xAxisBoilerplate : yAxisBoilerplate, attribute)},'); } + // buffer.write( + // 'left: ${_normalizeValue(xAxisBoilerplate, valueHolder.left)}, top: ${_normalizeValue(yAxisBoilerplate, valueHolder.top)},'); + // if (overrideChildDim) { + // buffer.write( + // 'width: ${_normalizeValue(xAxisBoilerplate, valueHolder.width)}, height: ${_normalizeValue(yAxisBoilerplate, valueHolder.height)},'); + // } else { + // buffer.write( + // 'right: ${_normalizeValue(xAxisBoilerplate, valueHolder.right)}, bottom: ${_normalizeValue(yAxisBoilerplate, valueHolder.bottom)},'); + // } source.child.currentContext = source.currentContext; buffer.write( @@ -90,7 +103,7 @@ class PBPositionedGenerator extends PBGenerator { return Tuple2('', ''); } - /// Going to return the value without the [preValueStatement] if the [value] + /// Going to return the value without the [preValueStatement] if the [positionalValue] /// is equal to `0`. /// /// The main purpose of this is to prevent reduntant multiplication, for example, @@ -98,11 +111,81 @@ class PBPositionedGenerator extends PBGenerator { /// MediaQuery.of(context).size.height * 0.0 /// ``` /// Where it should be `0`. - String _normalizeValue(String preValueStatement, double value) { - var n = double.parse(value.toStringAsFixed(3)); + String _normalizeValue(String preValueStatement, _PositionedValue positionalValue) { + var n = double.parse(positionalValue.value.toStringAsFixed(3)); if (n == 0) { return '0'; } + if(positionalValue.remainPointValue){ + return '$n'; + } return '$preValueStatement$n'; } + + List<_PositionedValue> _getPositionalAtt( + PositionedValueHolder positionedValueHolder, + PBIntermediateConstraints constrains) { + var attributes = <_PositionedValue>[]; + var fixedWidth = constrains.fixedWidth != null; + var fixedHeight = constrains.fixedHeight != null; + if (!(constrains.pinLeft && constrains.pinRight)) { + ///use [positionedValueHolder.left] + attributes + .add(_PositionedValue(positionedValueHolder.left, 'left', false)); + attributes.add( + _PositionedValue(positionedValueHolder.width, 'width', fixedWidth)); + } else if (constrains.pinLeft && !constrains.pinRight) { + ///use [positionedValueHolder.left] + attributes + .add(_PositionedValue(positionedValueHolder.left, 'left', true)); + attributes.add( + _PositionedValue(positionedValueHolder.width, 'width', fixedWidth)); + } else if (!constrains.pinLeft && constrains.pinRight) { + /// use [positionedValueHolder.right] + attributes + .add(_PositionedValue(positionedValueHolder.right, 'right', true)); + attributes.add( + _PositionedValue(positionedValueHolder.width, 'width', fixedWidth)); + } else if (constrains.pinLeft && constrains.pinRight) { + attributes + .add(_PositionedValue(positionedValueHolder.left, 'left', true)); + attributes + .add(_PositionedValue(positionedValueHolder.right, 'right', true)); + } + + ///Vertical constrains + if (!(constrains.pinTop && constrains.pinBottom)) { + attributes.add( + _PositionedValue(positionedValueHolder.top, 'top', false, false)); + attributes.add(_PositionedValue( + positionedValueHolder.height, 'height', fixedHeight, false)); + } else if (constrains.pinTop && !constrains.pinBottom) { + attributes + .add(_PositionedValue(positionedValueHolder.top, 'top', true, false)); + attributes.add(_PositionedValue( + positionedValueHolder.height, 'height', fixedHeight, false)); + } else if (!constrains.pinTop && constrains.pinBottom) { + /// use [positionedValueHolder.right] + attributes.add(_PositionedValue( + positionedValueHolder.bottom, 'bottom', true, false)); + attributes.add(_PositionedValue( + positionedValueHolder.height, 'height', fixedHeight, false)); + } else if (constrains.pinTop && constrains.pinBottom) { + attributes + .add(_PositionedValue(positionedValueHolder.top, 'top', true, false)); + attributes.add(_PositionedValue( + positionedValueHolder.bottom, 'bottom', true, false)); + } + return attributes; + } +} + +class _PositionedValue { + final String attributeName; + final bool remainPointValue; + final bool isXAxis; + double value; + + _PositionedValue(this.value, this.attributeName, this.remainPointValue, + [this.isXAxis = true]); } diff --git a/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart index 0815cfe8..d321d643 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart @@ -8,10 +8,15 @@ class PBDLConstraints { this.pinBottom, this.fixedHeight, this.fixedWidth}); + /// - If all the pins are `false` thats just means is going to scale normally. + /// - If there is a pin value that is `true` we are going to use the constant value for that + /// attribute instead of the scaling value(using media query). bool pinLeft; bool pinRight; bool pinTop; bool pinBottom; + + bool fixedHeight; bool fixedWidth; } From c9ae3b9cdd1dcba0efb3e70812063b0cedbaaf18 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 25 Jul 2021 19:55:16 -0600 Subject: [PATCH 259/404] FIX 486 with decresing the depth of where stack's dimension would become that of the canvas and uncommented some code that eliminated stack from being the rootNode --- lib/interpret_and_optimize/entities/layouts/stack.dart | 2 +- .../services/pb_layout_generation_service.dart | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index d8a55f3c..226a32fc 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -35,7 +35,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { /// childrend are being populated, and consequently [Stack.resize] is being /// called, then [depth] could be null. [depth] is null when the [PBIntermediateTree] /// has not finished creating and converting PBDL nodes into [PBIntermediateNode]. - if (depth != null && depth <= 2 && depth >= 0) { + if (depth != null && depth <= 1 && depth >= 0) { topLeftCorner = currentContext.canvasTLC; bottomRightCorner = currentContext.canvasBRC; } else { diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index c6982dee..e79a18f5 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -223,9 +223,9 @@ class PBLayoutGenerationService implements AITHandler { parent.replaceChildren(children); if (children.length == 1) { /// With the support for scaling & pinning, Stacks are now responsible for positioning. - // if (parent is PBIntermediateStackLayout) { - // return parent; - // } + if (parent is PBIntermediateStackLayout) { + return parent; + } return _replaceNode(parent, children[0]); } else { return parent is! TempGroupLayoutNode From 2cfb354447522bd747df6b30b454c710b99a65cd Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 25 Jul 2021 21:56:07 -0600 Subject: [PATCH 260/404] WIP REFACTORED the different ways of performing alignment on the [PBIntermediateNode]. --- lib/eggs/injected_app_bar.dart | 34 +++--- lib/eggs/injected_back_arrow.dart | 16 ++- lib/eggs/injected_tab.dart | 4 +- lib/eggs/injected_tab_bar.dart | 15 ++- .../entities/alignments/flexible.dart | 27 ++--- .../entities/alignments/padding.dart | 24 ++--- .../entities/alignments/spacer.dart | 14 +-- .../entities/inherited_bitmap.dart | 8 +- .../entities/inherited_circle.dart | 14 --- .../entities/inherited_container.dart | 53 +++++----- .../entities/inherited_oval.dart | 7 +- .../entities/inherited_polygon.dart | 5 +- .../entities/inherited_scaffold.dart | 20 +--- .../entities/inherited_shape_group.dart | 5 +- .../entities/inherited_shape_path.dart | 4 +- .../entities/inherited_star.dart | 5 +- .../entities/inherited_text.dart | 5 +- .../entities/inherited_triangle.dart | 5 +- .../entities/injected_container.dart | 19 +--- .../entities/layouts/column.dart | 100 ++++++++++-------- .../entities/layouts/row.dart | 87 ++++++++------- .../entities/layouts/stack.dart | 69 ++++++------ .../layouts/temp_group_layout_node.dart | 7 +- .../entities/pb_shared_instance.dart | 20 +--- .../entities/pb_shared_master_node.dart | 9 +- .../subclasses/pb_intermediate_node.dart | 27 +++-- .../pb_layout_intermediate_node.dart | 11 +- .../pb_visual_intermediate_node.dart | 5 +- .../helpers/align_strategy.dart | 30 ++++++ .../helpers/pb_context.dart | 7 ++ .../pb_alignment_generation_service.dart | 10 +- .../pb_symbol_master_params.dart | 5 +- 32 files changed, 305 insertions(+), 366 deletions(-) create mode 100644 lib/interpret_and_optimize/helpers/align_strategy.dart diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 991a5d68..3f3d983f 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -5,19 +5,17 @@ import 'package:parabeac_core/interpret_and_optimize/entities/injected_container import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { - @override - PBContext currentContext; - @override String semanticName = ''; @override - String UUID; + AlignStrategy alignStrategy = CustomAppBarAlignment(); @override List get children => @@ -31,8 +29,8 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { getAttributeNamed('actions')?.attributeNode; InjectedAppbar( - Point topLeftCorner, Point bottomRightCorner, this.UUID, String name, - {this.currentContext}) + Point topLeftCorner, Point bottomRightCorner, String UUID, String name, + {PBContext currentContext}) : super(topLeftCorner, bottomRightCorner, currentContext, name) { generator = PBAppBarGenerator(); addAttribute(PBAttribute('leading')); @@ -67,17 +65,6 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { return; } - @override - void alignChild() { - /// This align only modifies middleItem - var tempNode = InjectedContainer(middleItem.bottomRightCorner, - middleItem.topLeftCorner, middleItem.name, middleItem.UUID, - currentContext: currentContext, constraints: middleItem.constraints) - ..addChild(middleItem); - - getAttributeNamed('title').attributeNode = tempNode; - } - @override PBEgg generatePluginNode( Point topLeftCorner, Point bottomRightCorner, originalRef) { @@ -94,7 +81,18 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override void extractInformation(DesignNode incomingNode) {} } - +class CustomAppBarAlignment extends AlignStrategy{ + @override + void align(PBContext context, InjectedAppbar node) { + /// This align only modifies middleItem + var tempNode = InjectedContainer(node.middleItem.bottomRightCorner, + node.middleItem.topLeftCorner, node.middleItem.name, node.middleItem.UUID, + currentContext: node.currentContext, constraints: node.middleItem.constraints) + ..addChild(node.middleItem); + + node.getAttributeNamed('title').attributeNode = tempNode; + } +} class PBAppBarGenerator extends PBGenerator { PBAppBarGenerator() : super(); diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index dd7487aa..19549a52 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -3,16 +3,12 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { - @override - PBContext currentContext; - - @override - final String UUID; @override String semanticName = ''; @@ -20,17 +16,17 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { @override ChildrenStrategy childrenStrategy = NoChildStrategy(); + @override + AlignStrategy alignStrategy = NoAlignment(); + InjectedBackArrow( - Point topLeftCorner, Point bottomRightCorner, this.UUID, String name, - {this.currentContext}) + Point topLeftCorner, Point bottomRightCorner, String UUID, String name, + {PBContext currentContext}) : super(topLeftCorner, bottomRightCorner, currentContext, name) { generator = PBBackArrowGenerator(); } - @override - void alignChild() {} - @override void extractInformation(DesignNode incomingNode) {} diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 0d86231c..f45ece1d 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; @@ -60,9 +61,6 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { return tab; } - @override - void alignChild() {} - @override List layoutInstruction(List layer) { return layer; diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 5d1624ca..93e3a758 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -6,27 +6,28 @@ import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart' import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; import 'injected_tab.dart'; class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { - @override - final String UUID; - @override - PBContext currentContext; + @override String semanticName = ''; List get tabs => getAttributeNamed('tabs').attributeNodes; + @override + AlignStrategy alignStrategy = NoAlignment(); + InjectedTabBar( Point topLeftCorner, Point bottomRightCorner, String name, - this.UUID, { - this.currentContext, + String UUID, { + PBContext currentContext, }) : super(topLeftCorner, bottomRightCorner, currentContext, name) { generator = PBTabBarGenerator(); addAttribute(PBAttribute('tabs')); @@ -52,8 +53,6 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override List layoutInstruction(List layer) {} - @override - void alignChild() {} @override PBEgg generatePluginNode( diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index a758341e..6b2b48eb 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -1,30 +1,28 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_flexible_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; + class Flexible extends PBVisualIntermediateNode { int flex; - @override - var currentContext; - - @override - final String UUID; - @override ChildrenStrategy childrenStrategy = OneChildStrategy('child'); + //TODO: Find a way to make currentContext required //without breaking the json serializable Flexible( - this.UUID, { - this.currentContext, + String UUID, { + PBContext currentContext, child, this.flex, - this.topLeftCorner, - this.bottomRightCorner, + Point topLeftCorner, + Point bottomRightCorner, }) : super( topLeftCorner, bottomRightCorner, @@ -35,13 +33,4 @@ class Flexible extends PBVisualIntermediateNode { generator = PBFlexibleGenerator(); this.child = child; } - - @override - Point topLeftCorner; - - @override - Point bottomRightCorner; - - @override - void alignChild() {} } diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index 7e262d7e..a86a7acc 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -2,6 +2,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_padding_ge import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; @@ -9,34 +10,24 @@ import 'dart:math'; class Padding extends PBVisualIntermediateNode { double left, right, top, bottom, screenWidth, screenHeight; - @override - final String UUID; Map padding; - @override - PBContext currentContext; - - @override - Point topLeftCorner; - - @override - Point bottomRightCorner; - PBIntermediateConstraints childToParentConstraints; @override ChildrenStrategy childrenStrategy = OneChildStrategy('child'); + Padding( - this.UUID, + String UUID, this.childToParentConstraints, { this.left = 0, this.right = 0, this.top = 0, this.bottom = 0, - this.topLeftCorner, - this.bottomRightCorner, - this.currentContext, + Point topLeftCorner, + Point bottomRightCorner, + PBContext currentContext, }) : super(topLeftCorner, bottomRightCorner, currentContext, '', UUID: UUID) { generator = PBPaddingGen(); } @@ -81,7 +72,4 @@ class Padding extends PBVisualIntermediateNode { bottom = bottom < 0.01 ? 0.0 : bottom; } } - - @override - void alignChild() {} } diff --git a/lib/interpret_and_optimize/entities/alignments/spacer.dart b/lib/interpret_and_optimize/entities/alignments/spacer.dart index 2d39c3aa..08a8d5ab 100644 --- a/lib/interpret_and_optimize/entities/alignments/spacer.dart +++ b/lib/interpret_and_optimize/entities/alignments/spacer.dart @@ -1,27 +1,21 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_spacer_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class Spacer extends PBVisualIntermediateNode { int flex; - @override - final String UUID; - - @override - PBContext currentContext; @override ChildrenStrategy childrenStrategy = NoChildStrategy(); - Spacer(topLeftCorner, bottomRightCorner, this.UUID, - {this.flex, this.currentContext}) + + Spacer(topLeftCorner, bottomRightCorner, String UUID, + {this.flex, PBContext currentContext}) : super(topLeftCorner, bottomRightCorner, currentContext, '', UUID: UUID) { generator = PBSpacerGenerator(); } - - @override - void alignChild() {} } diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index 6079e346..38723fb5 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; @@ -26,7 +27,6 @@ class InheritedBitmap extends PBVisualIntermediateNode @override ChildrenStrategy childrenStrategy = NoChildStrategy(); - var log = Logger('Inherited Bitmap'); String referenceImage; @@ -53,7 +53,7 @@ class InheritedBitmap extends PBVisualIntermediateNode if (originalRef.name == null || (originalRef as Image).imageReference == null) { - log.debug('NULL BITMAP'); + logger.debug('NULL BITMAP'); } name = (originalRef as Image).imageReference; size = { @@ -65,8 +65,4 @@ class InheritedBitmap extends PBVisualIntermediateNode originalRef.UUID, '${MainInfo().outputPath}assets/images'); } - @override - void alignChild() { - return; - } } diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 485b33b1..3ceacf29 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -40,18 +40,4 @@ class InheritedCircle extends PBVisualIntermediateNode auxiliaryData.borderInfo = {}; auxiliaryData.borderInfo['shape'] = 'circle'; } - - @override - void alignChild() { - // var padding = Padding('', child.constraints, - // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), - // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), - // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), - // bottom: (child.bottomRightCorner.y - bottomRightCorner.y).abs(), - // topLeftCorner: topLeftCorner, - // bottomRightCorner: bottomRightCorner, - // currentContext: currentContext); - // padding.addChild(child); - // child = padding; - } } diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index e103da3e..e1324b72 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -11,6 +11,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -28,6 +29,10 @@ class InheritedContainer extends PBVisualIntermediateNode @override ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); + /// TODO: switch to padding + @override + AlignStrategy alignStrategy = NoAlignment(); + InheritedContainer(this.originalRef, Point topLeftCorner, Point bottomRightCorner, String name, {double alignX, @@ -69,28 +74,28 @@ class InheritedContainer extends PBVisualIntermediateNode 'A null original reference was sent to an PBInheritedIntermediate Node'); } - @override - void alignChild() { - if (child != null) { - /// Refactor to child.constraints != null - if (child is! InheritedText) { - // var left = (child.topLeftCorner.x - topLeftCorner.x).abs() ?? 0.0; - // var right = - // (bottomRightCorner.x - child.bottomRightCorner.x).abs() ?? 0.0; - // var top = (child.topLeftCorner.y - topLeftCorner.y).abs() ?? 0.0; - // var bottom = - // (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0; - // var padding = Padding('', child.constraints, - // left: left, - // right: right, - // top: top, - // bottom: bottom, - // topLeftCorner: topLeftCorner, - // bottomRightCorner: bottomRightCorner, - // currentContext: currentContext); - // padding.addChild(child); - // child = padding; - } - } - } + // @override + // void alignChild() { + // if (child != null) { + // /// Refactor to child.constraints != null + // if (child is! InheritedText) { + // // var left = (child.topLeftCorner.x - topLeftCorner.x).abs() ?? 0.0; + // // var right = + // // (bottomRightCorner.x - child.bottomRightCorner.x).abs() ?? 0.0; + // // var top = (child.topLeftCorner.y - topLeftCorner.y).abs() ?? 0.0; + // // var bottom = + // // (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0; + // // var padding = Padding('', child.constraints, + // // left: left, + // // right: right, + // // top: top, + // // bottom: bottom, + // // topLeftCorner: topLeftCorner, + // // bottomRightCorner: bottomRightCorner, + // // currentContext: currentContext); + // // padding.addChild(child); + // // child = padding; + // } + // } + // } } diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index c31b6f51..595cc37e 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; @@ -19,7 +20,6 @@ class InheritedOval extends PBVisualIntermediateNode implements PBInheritedIntermediate { @override var originalRef; - var log = Logger('Layout Generation Service'); @override ChildrenStrategy childrenStrategy = NoChildStrategy(); @@ -59,9 +59,4 @@ class InheritedOval extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - - @override - void alignChild() { - // Images don't have children. - } } diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index 9dfe53cf..a3c6eab8 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; @@ -56,8 +57,4 @@ class InheritedPolygon extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - @override - void alignChild() { - // Images don't hae children. - } } diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 5ac5ea7e..19b47ee5 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -12,6 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -27,6 +28,9 @@ class InheritedScaffold extends PBVisualIntermediateNode bool isHomeScreen = false; + @override + AlignStrategy alignStrategy = PaddingAlignment(); + @override PBIntermediateNode get child => getAttributeNamed('body')?.attributeNode; @@ -126,20 +130,4 @@ class InheritedScaffold extends PBVisualIntermediateNode } } } - - @override - void alignChild() { - if (child != null) { - // var padding = Padding('', child.constraints, - // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), - // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), - // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), - // bottom: (bottomRightCorner.y - child.bottomRightCorner.y).abs(), - // topLeftCorner: topLeftCorner, - // bottomRightCorner: bottomRightCorner, - // currentContext: currentContext); - // padding.addChild(child); - // child = padding; - } - } } diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index b6801465..e0bb287d 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; @@ -57,8 +58,4 @@ class InheritedShapeGroup extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - @override - void alignChild() { - // Images don't have children. - } } diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 44aafdf8..490e116f 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -12,6 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; @@ -100,7 +101,4 @@ class InheritedShapePath extends PBVisualIntermediateNode return isVertical || isHorizontal; } - - @override - void alignChild() {} } diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index 6173ae2c..1fbdf328 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; @@ -56,8 +57,4 @@ class InheritedStar extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - @override - void alignChild() { - // Images don't have children. - } } diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 84c491fd..d6baf860 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -80,8 +81,4 @@ class InheritedText extends PBVisualIntermediateNode return text.replaceAll('\$', '\\\$'); } - @override - void alignChild() { - // Text don't have children. - } } diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index c92cfdcd..759d33d3 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; @@ -57,8 +58,4 @@ class InheritedTriangle extends PBVisualIntermediateNode UUID, '${MainInfo().outputPath}assets/images', image); } - @override - void alignChild() { - // Images don't have children. - } } diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index ab95a808..3b06c4ff 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -20,6 +21,9 @@ class InjectedContainer extends PBVisualIntermediateNode @override ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); + @override + AlignStrategy alignStrategy = PaddingAlignment(); + InjectedContainer( Point bottomRightCorner, Point topLeftCorner, @@ -38,19 +42,4 @@ class InjectedContainer extends PBVisualIntermediateNode }; } - - @override - void alignChild() { - /// Add Padding that takes into account pinning (hard values). - // var padding = Padding('', child.constraints, - // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), - // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), - // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), - // bottom: (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0, - // topLeftCorner: topLeftCorner, - // bottomRightCorner: bottomRightCorner, - // currentContext: currentContext); - // padding.child = child; - // child = padding; - } } diff --git a/lib/interpret_and_optimize/entities/layouts/column.dart b/lib/interpret_and_optimize/entities/layouts/column.dart index 3b54151b..d5653cb9 100644 --- a/lib/interpret_and_optimize/entities/layouts/column.dart +++ b/lib/interpret_and_optimize/entities/layouts/column.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/axis import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/handle_flex.dart'; @@ -24,6 +25,9 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { @override PrototypeNode prototypeNode; + @override + AlignStrategy alignStrategy = ColumnAlignment(); + PBIntermediateColumnLayout( PBContext currentContext, {String name}) : super(COLUMN_RULES, COLUMN_EXCEPTIONS, currentContext, name) { @@ -31,65 +35,69 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { } @override - void alignChildren() { - checkCrossAxisAlignment(); - _invertAlignment(); - if (currentContext.configuration.widgetSpacing == 'Expanded') { - _addPerpendicularAlignment(); - _addParallelAlignment(); + PBLayoutIntermediateNode generateLayout(List children, + PBContext currentContext, String name) { + var col = PBIntermediateColumnLayout(currentContext, name: name); + col.prototypeNode = prototypeNode; + children.forEach((child) => col.addChild(child)); + return col; + } + + @override + void addChild(node) => addChildToLayout(node); + + +} + +class ColumnAlignment extends AlignStrategy{ + + /// Invert method for Column alignment + void _invertAlignment(PBIntermediateColumnLayout node) { + if (node.alignment.isNotEmpty) { + var tempCrossAxis = node.alignment['crossAxisAlignment']; + var tempMainAxis = node.alignment['mainAxisAlignment']; + node.alignment['crossAxisAlignment'] = tempMainAxis; + node.alignment['mainAxisAlignment'] = tempCrossAxis; + } + } + @override + void align(PBContext context, PBIntermediateColumnLayout node) { + node.checkCrossAxisAlignment(); + _invertAlignment(node); + if (node.currentContext.configuration.widgetSpacing == 'Expanded') { + _addPerpendicularAlignment(node); + _addParallelAlignment(node); } else { assert(false, - 'We don\'t support Configuration [${currentContext.configuration.widgetSpacing}] yet.'); + 'We don\'t support Configuration [${node.currentContext.configuration.widgetSpacing}] yet.'); } } - void _addParallelAlignment() { - var newchildren = handleFlex(true, topLeftCorner, bottomRightCorner, - children?.cast()); - replaceChildren(newchildren); + void _addParallelAlignment(PBIntermediateColumnLayout node) { + var newchildren = handleFlex(true, node.topLeftCorner, node.bottomRightCorner, + node.children?.cast()); + node.replaceChildren(newchildren); } - void _addPerpendicularAlignment() { - var columnMinX = topLeftCorner.x; - var columnMaxX = bottomRightCorner.x; + void _addPerpendicularAlignment(PBIntermediateColumnLayout node) { + var columnMinX = node.topLeftCorner.x; + var columnMaxX = node.bottomRightCorner.x; - for (var i = 0; i < children.length; i++) { - var padding = Padding('', children[i].constraints, - left: children[i].topLeftCorner.x - columnMinX ?? 0.0, - right: columnMaxX - children[i].bottomRightCorner.x ?? 0.0, + for (var i = 0; i < node.children.length; i++) { + var padding = Padding('', node.children[i].constraints, + left: node.children[i].topLeftCorner.x - columnMinX ?? 0.0, + right: columnMaxX - node.children[i].bottomRightCorner.x ?? 0.0, top: 0.0, bottom: 0.0, - topLeftCorner: children[i].topLeftCorner, - bottomRightCorner: children[i].bottomRightCorner, - currentContext: currentContext); - padding.addChild(children[i]); + topLeftCorner: node.children[i].topLeftCorner, + bottomRightCorner: node.children[i].bottomRightCorner, + currentContext: node.currentContext); + padding.addChild(node.children[i]); //Replace Children. - var childrenCopy = children; + var childrenCopy = node.children; childrenCopy[i] = padding; - replaceChildren(childrenCopy?.cast()); - } - } - - @override - PBLayoutIntermediateNode generateLayout(List children, - PBContext currentContext, String name) { - var col = PBIntermediateColumnLayout(currentContext, name: name); - col.prototypeNode = prototypeNode; - children.forEach((child) => col.addChild(child)); - return col; - } - - @override - void addChild(node) => addChildToLayout(node); - - /// Invert method for Column alignment - void _invertAlignment() { - if (alignment.isNotEmpty) { - var tempCrossAxis = alignment['crossAxisAlignment']; - var tempMainAxis = alignment['mainAxisAlignment']; - alignment['crossAxisAlignment'] = tempMainAxis; - alignment['mainAxisAlignment'] = tempCrossAxis; + node.replaceChildren(childrenCopy?.cast()); } } } diff --git a/lib/interpret_and_optimize/entities/layouts/row.dart b/lib/interpret_and_optimize/entities/layouts/row.dart index 5671e211..af00909a 100644 --- a/lib/interpret_and_optimize/entities/layouts/row.dart +++ b/lib/interpret_and_optimize/entities/layouts/row.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/hand import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; ///Row contains nodes that are all `horizontal` to each other, without overlapping eachother @@ -22,6 +23,9 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { @override PrototypeNode prototypeNode; + @override + AlignStrategy alignStrategy = RowAlignment(); + PBIntermediateRowLayout(PBContext currentContext, {String name}) : super(ROW_RULES, ROW_EXCEPTIONS, currentContext, name) { generator = PBRowGenerator(); @@ -31,63 +35,66 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { void addChild(node) => addChildToLayout(node); @override - void alignChildren() { - checkCrossAxisAlignment(); - if (currentContext.configuration.widgetSpacing == 'Expanded') { - _addPerpendicularAlignment(); - _addParallelAlignment(); + PBLayoutIntermediateNode generateLayout(List children, + PBContext currentContext, String name) { + var row = PBIntermediateRowLayout(currentContext, name: name); + row.prototypeNode = prototypeNode; + children.forEach((child) => row.addChild(child)); + return row; + } + + @override + void sortChildren() => replaceChildren(children + ..sort((child0, child1) => + child0.topLeftCorner.x.compareTo(child1.topLeftCorner.x))); +} + +class RowAlignment extends AlignStrategy{ + @override + void align(PBContext context, PBIntermediateRowLayout node) { + node.checkCrossAxisAlignment(); + if (node.currentContext.configuration.widgetSpacing == 'Expanded') { + _addPerpendicularAlignment(node); + _addParallelAlignment(node); } else { assert(false, - 'We don\'t support Configuration [${currentContext.configuration.widgetSpacing}] yet.'); + 'We don\'t support Configuration [${node.currentContext.configuration.widgetSpacing}] yet.'); } } - void _addParallelAlignment() { - var newchildren = handleFlex(false, topLeftCorner, bottomRightCorner, - children?.cast()); - replaceChildren(newchildren); + void _addParallelAlignment(PBIntermediateRowLayout node) { + var newchildren = handleFlex(false, node.topLeftCorner, node.bottomRightCorner, + node.children?.cast()); + node.replaceChildren(newchildren); } - void _addPerpendicularAlignment() { - var rowMinY = topLeftCorner.y; - var rowMaxY = bottomRightCorner.y; + void _addPerpendicularAlignment(PBIntermediateRowLayout node) { + var rowMinY = node.topLeftCorner.y; + var rowMaxY = node.bottomRightCorner.y; - if (topLeftCorner.y < currentContext.screenTopLeftCorner.y) { - rowMinY = currentContext.screenTopLeftCorner.y; + if (node.topLeftCorner.y < node.currentContext.screenTopLeftCorner.y) { + rowMinY = node.currentContext.screenTopLeftCorner.y; } - if (bottomRightCorner.y > currentContext.screenBottomRightCorner.y) { - rowMaxY = currentContext.screenBottomRightCorner.y; + if (node.bottomRightCorner.y > node.currentContext.screenBottomRightCorner.y) { + rowMaxY = node.currentContext.screenBottomRightCorner.y; } - for (var i = 0; i < children.length; i++) { - var padding = Padding('', children[i].constraints, - top: children[i].topLeftCorner.y - rowMinY ?? 0.0, - bottom: rowMaxY - children[i].bottomRightCorner.y ?? 0.0, + for (var i = 0; i < node.children.length; i++) { + var padding = Padding('', node.children[i].constraints, + top: node.children[i].topLeftCorner.y - rowMinY ?? 0.0, + bottom: rowMaxY - node.children[i].bottomRightCorner.y ?? 0.0, left: 0.0, right: 0.0, - topLeftCorner: children[i].topLeftCorner, - bottomRightCorner: children[i].bottomRightCorner, - currentContext: currentContext); - padding.addChild(children[i]); + topLeftCorner: node.children[i].topLeftCorner, + bottomRightCorner: node.children[i].bottomRightCorner, + currentContext: node.currentContext); + padding.addChild(node.children[i]); //Replace Children. - var childrenCopy = children; + var childrenCopy = node.children; childrenCopy[i] = padding; - replaceChildren(childrenCopy); + node.replaceChildren(childrenCopy); } } - @override - PBLayoutIntermediateNode generateLayout(List children, - PBContext currentContext, String name) { - var row = PBIntermediateRowLayout(currentContext, name: name); - row.prototypeNode = prototypeNode; - children.forEach((child) => row.addChild(child)); - return row; - } - - @override - void sortChildren() => replaceChildren(children - ..sort((child0, child1) => - child0.topLeftCorner.x.compareTo(child1.topLeftCorner.x))); } diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 226a32fc..d980a7e8 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/axis import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:uuid/uuid.dart'; @@ -19,6 +20,8 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { @override PrototypeNode prototypeNode; + AlignStrategy alignStrategy = PositionedAlignment(); + PBIntermediateStackLayout(PBContext currentContext, {String name}) : super(STACK_RULES, [], currentContext, name) { generator = PBStackGenerator(); @@ -43,42 +46,6 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { } } - /// Do we need to subtract some sort of offset? Maybe child.topLeftCorner.x - topLeftCorner.x? - @override - void alignChildren() { - var alignedChildren = []; - for (var child in children) { - if (child.topLeftCorner == topLeftCorner && - child.bottomRightCorner == bottomRightCorner) { - //if they are the same size then there is no need for adjusting. - alignedChildren.add(child); - continue; - } - - double top, bottom, left, right; - - top = child.topLeftCorner.y - topLeftCorner.y; - bottom = bottomRightCorner.y - child.bottomRightCorner.y; - - left = child.topLeftCorner.x - topLeftCorner.x; - right = bottomRightCorner.x - child.bottomRightCorner.x; - - alignedChildren.add(InjectedPositioned( - Uuid().v4(), child.topLeftCorner.clone(), child.bottomRightCorner.clone(), - valueHolder: PositionedValueHolder( - top: top, - bottom: bottom, - left: left, - right: right, - height: child.height, - width: child.width), - currentContext: currentContext, - constraints: child.constraints) - ..addChild(child)); - } - replaceChildren(alignedChildren); - } - @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { @@ -89,3 +56,33 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { return stack; } } + +class PositionedAlignment extends AlignStrategy { + /// Do we need to subtract some sort of offset? Maybe child.topLeftCorner.x - topLeftCorner.x? + + @override + void align(PBContext context, PBIntermediateStackLayout node) { + var alignedChildren = []; + node.children.skipWhile((child) { + /// if they are the same size then there is no need for adjusting. + if (child.topLeftCorner == node.topLeftCorner && + child.bottomRightCorner == node.bottomRightCorner) { + alignedChildren.add(child); + return true; + } + return false; + }).forEach((child) { + alignedChildren.add(InjectedPositioned(Uuid().v4(), + child.topLeftCorner.clone(), child.bottomRightCorner.clone(), + constraints: child.constraints, + currentContext: context, + valueHolder: PositionedValueHolder( + top: child.topLeftCorner.y - node.topLeftCorner.y, + bottom: node.bottomRightCorner.y - child.bottomRightCorner.y, + left: child.topLeftCorner.x - node.topLeftCorner.x, + right: node.bottomRightCorner.x - child.bottomRightCorner.x)) + ..addChild(child)); + }); + node.replaceChildren(alignedChildren); + } +} diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index 31e1d0d4..a5138275 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; /// A temporary node that must be removed @@ -29,12 +30,6 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode addChildToLayout(node); } - @override - void alignChildren() { - assert(false, 'Attempted to align children on class type [$runtimeType]'); - return null; - } - @override bool satisfyRules( PBIntermediateNode currentNode, PBIntermediateNode nextNode) { diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index c498fc20..305503ca 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; @@ -41,6 +42,9 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @override ChildrenStrategy childrenStrategy = NoChildStrategy(); + @override + AlignStrategy alignStrategy = PaddingAlignment(); + List overrideValues; // quick lookup based on UUID_type Map overrideValuesMap = {}; @@ -77,22 +81,6 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode ..removeWhere((v) => v == null || v.value == null); } - @override - void alignChild() { - if (child != null) { - // var padding = Padding('', child.constraints, - // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), - // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), - // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), - // bottom: - // (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0, - // topLeftCorner: topLeftCorner, - // bottomRightCorner: bottomRightCorner, - // currentContext: currentContext); - // padding.addChild(child); - // child = padding; - } - } } class PBSharedParameterValue { diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index b359e036..a7002603 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -10,14 +10,13 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; import 'package:quick_log/quick_log.dart'; class PBSharedMasterNode extends PBVisualIntermediateNode implements PBInheritedIntermediate { - ///SERVICE - var log = Logger('PBSharedMasterNode'); @override final originalRef; @@ -71,9 +70,8 @@ class PBSharedMasterNode extends PBVisualIntermediateNode exception: e, stackTrace: stackTrace, ); - log.error(e.toString()); + logger.error(e.toString()); } - ; if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); @@ -109,9 +107,6 @@ class PBSharedMasterNode extends PBVisualIntermediateNode @override void addChild(node) => child == null ? child = node : children = [node]; - - @override - void alignChild() {} } class PBSharedParameterProp { diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 26446a2f..9db48f3e 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -15,7 +16,7 @@ import 'package:quick_log/quick_log.dart'; /// Usually, we work with its subclasses. We normalize several aspects of data that a sketch node presents in order to work better at the intermediate level. /// Sometimes, PBNode’s do not have a direct representation of a sketch node. For example, most layout nodes are primarily made through and understanding of a need for a layout. abstract class PBIntermediateNode extends TraversableNode { - static final logger = Logger('PBIntermediateNode'); + Logger logger; /// A subsemantic is contextual info to be analyzed in or in-between the visual generation & layout generation services. String subsemantic; @@ -38,6 +39,8 @@ abstract class PBIntermediateNode extends TraversableNode { List get children => [child]; ChildrenStrategy childrenStrategy = OneChildStrategy('child'); + + AlignStrategy alignStrategy = NoAlignment(); /// Gets the [PBIntermediateNode] at attribute `child` PBIntermediateNode get child => getAttributeNamed('child')?.attributeNode; @@ -57,7 +60,7 @@ abstract class PBIntermediateNode extends TraversableNode { Point topLeftCorner; Point bottomRightCorner; - + double get width => (bottomRightCorner.x - topLeftCorner.x).toDouble(); double get height => (bottomRightCorner.y - topLeftCorner.y).toDouble(); @@ -76,6 +79,7 @@ abstract class PBIntermediateNode extends TraversableNode { PBIntermediateNode( this.topLeftCorner, this.bottomRightCorner, this.UUID, this.name, {this.currentContext, this.subsemantic, this.constraints}) { + logger = Logger(runtimeType.toString()); _attributes = []; _pointCorrection(); } @@ -141,12 +145,23 @@ abstract class PBIntermediateNode extends TraversableNode { return true; } + /// These are the constrains that are going to be used by the sub tree. + void _setSubTreeConstrains(PBIntermediateConstraints constraints) {} + /// Adds child to node. - void addChild(node){ + void addChild(node) { childrenStrategy.addChild(this, node); + + /// Checking the constrains of the [node] being added to the tree, smoe of the + /// constrains could be inherited to that section of the sub-tree. + } + + void align(PBContext context) { + alignStrategy.align(context, this); } } -extension PBPointLegacyMethod on Point{ + +extension PBPointLegacyMethod on Point { Point clone() => Point(x, y); // TODO: This is a temporal fix ----- Not sure why there some sort of safe area for the y-axis?? @@ -155,7 +170,7 @@ extension PBPointLegacyMethod on Point{ y == anotherPoint.y || (y.abs() - anotherPoint.y.abs()).abs() < 3 ? x.compareTo(anotherPoint.x) : y.compareTo(anotherPoint.y); - + bool operator <(Object point) { if (point is Point) { return y == point.y ? x <= point.x : y <= point.y; @@ -169,4 +184,4 @@ extension PBPointLegacyMethod on Point{ } return false; } -} \ No newline at end of file +} diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index 87949488..2741ab35 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/exceptions import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:uuid/uuid.dart'; @@ -44,15 +45,13 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode addAttribute(PBAttribute('children')); } - void alignChildren(); - ///Replace the current children with the [children] void replaceChildren(List children) { if (children.isNotEmpty) { getAttributeNamed('children')?.attributeNodes = children; resize(); } else { - PBIntermediateNode.logger.warning( + logger.warning( 'Trying to add a list of children to the $runtimeType that is either null or empty'); } } @@ -75,7 +74,7 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode void resize() { if (children.isEmpty) { - PBIntermediateNode.logger + logger .warning('There should be children in the layout so it can resize.'); return; } @@ -170,4 +169,6 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode } } } -} \ No newline at end of file +} + + diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart index 88715198..ec0f490c 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart @@ -2,17 +2,20 @@ import 'dart:math'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; // import 'dart:math'; /// Represents a typical node that the end-user could see, it usually has properties such as size and color. It only contains a single child, unlike PBLayoutIntermediateNode that contains a set of children. /// Superclass: PBIntermediateNode abstract class PBVisualIntermediateNode extends PBIntermediateNode { + + PBVisualIntermediateNode(Point topLeftCorner, Point bottomRightCorner, PBContext currentContext, String name, {String UUID, PBIntermediateConstraints constraints}) : super(topLeftCorner, bottomRightCorner, UUID, name, currentContext: currentContext, constraints: constraints); - void alignChild(); + } diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart new file mode 100644 index 00000000..abea1f12 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -0,0 +1,30 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; + +abstract class AlignStrategy{ + void align(PBContext context, T node); +} + +class PaddingAlignment extends AlignStrategy{ + @override + void align(PBContext context, PBIntermediateNode node) { + var padding = Padding('', node.child.constraints, + left: (node.child.topLeftCorner.x - node.topLeftCorner.x).abs(), + right: (node.bottomRightCorner.x - node.child.bottomRightCorner.x).abs(), + top: (node.child.topLeftCorner.y - node.topLeftCorner.y).abs(), + bottom: (node.child.bottomRightCorner.y - node.bottomRightCorner.y).abs(), + topLeftCorner: node.topLeftCorner, + bottomRightCorner: node.bottomRightCorner, + currentContext: node.currentContext); + padding.addChild(node.child); + node.child = padding; + } +} + +class NoAlignment extends AlignStrategy{ + @override + void align(PBContext context, PBIntermediateNode node) { + + } +} \ No newline at end of file diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 9e2b228a..52d5ee96 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; @@ -42,6 +43,12 @@ class PBContext { Point canvasTLC; Point canvasBRC; + /// The [constextConstrains] represents the costraints that would be inherited by a section of the tree. + /// + /// For example, when there is a [InjectedPositioned] that contains [contextConstraints.fixedWidth], then + /// all of the [InjectedPositioned.child] subtree should inherit that information. + PBIntermediateConstraints contextConstraints = PBIntermediateConstraints(); + PBIntermediateTree tree; PBProject project; SizingValueContext sizingContext = SizingValueContext.PointValue; diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index 83bf8c47..23c27468 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -26,15 +26,7 @@ class PBAlignGenerationService implements AITHandler { return null; } - tree.forEach((node) { - if(node is PBVisualIntermediateNode){ - node.alignChild(); - } - if(node is PBLayoutIntermediateNode){ - // TODO: convert to using aling() on each node. - node.alignChildren(); - } - }); + tree.forEach((node) => node.align(context)); return Future.value(tree); } diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart index aa132a78..ba7ebebe 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart @@ -2,6 +2,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; @@ -44,8 +45,4 @@ class PBSymbolMasterParameter extends PBVisualIntermediateNode //TODO: return a more specified Type return PBIntermediateNode; } - - - @override - void alignChild() {} } From 01a1c987c69b3e675c23299711662acaca9071ce Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 25 Jul 2021 22:15:56 -0600 Subject: [PATCH 261/404] WIP made the REFACTOR for alignment work on each padding configuration. --- lib/interpret_and_optimize/entities/inherited_scaffold.dart | 2 +- lib/interpret_and_optimize/entities/injected_container.dart | 2 +- lib/interpret_and_optimize/entities/layouts/stack.dart | 5 ++++- lib/interpret_and_optimize/entities/pb_shared_instance.dart | 2 +- .../services/pb_alignment_generation_service.dart | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 19b47ee5..a04c8c11 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -29,7 +29,7 @@ class InheritedScaffold extends PBVisualIntermediateNode bool isHomeScreen = false; @override - AlignStrategy alignStrategy = PaddingAlignment(); + AlignStrategy alignStrategy = NoAlignment();//PaddingAlignment(); @override PBIntermediateNode get child => getAttributeNamed('body')?.attributeNode; diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 3b06c4ff..d6a62363 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -22,7 +22,7 @@ class InjectedContainer extends PBVisualIntermediateNode ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); @override - AlignStrategy alignStrategy = PaddingAlignment(); + AlignStrategy alignStrategy = NoAlignment();//PaddingAlignment(); InjectedContainer( Point bottomRightCorner, diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index d980a7e8..faac8c7b 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -20,6 +20,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { @override PrototypeNode prototypeNode; + @override AlignStrategy alignStrategy = PositionedAlignment(); PBIntermediateStackLayout(PBContext currentContext, {String name}) @@ -80,7 +81,9 @@ class PositionedAlignment extends AlignStrategy { top: child.topLeftCorner.y - node.topLeftCorner.y, bottom: node.bottomRightCorner.y - child.bottomRightCorner.y, left: child.topLeftCorner.x - node.topLeftCorner.x, - right: node.bottomRightCorner.x - child.bottomRightCorner.x)) + right: node.bottomRightCorner.x - child.bottomRightCorner.x, + width: child.width, + height: child.height)) ..addChild(child)); }); node.replaceChildren(alignedChildren); diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 305503ca..de775ac4 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -43,7 +43,7 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode ChildrenStrategy childrenStrategy = NoChildStrategy(); @override - AlignStrategy alignStrategy = PaddingAlignment(); + AlignStrategy alignStrategy = NoAlignment();//PaddingAlignment(); List overrideValues; // quick lookup based on UUID_type diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index 23c27468..d6671d46 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -26,7 +26,7 @@ class PBAlignGenerationService implements AITHandler { return null; } - tree.forEach((node) => node.align(context)); + tree.forEach((node) => node?.align(context)); return Future.value(tree); } From d85c20a8360521579b9f26c3f6d0b0970d06eb9d Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 25 Jul 2021 22:23:54 -0600 Subject: [PATCH 262/404] WIP reflected the fixed height and fixed width in the context --- .../entities/layouts/stack.dart | 32 ------------- .../subclasses/pb_intermediate_node.dart | 3 -- .../helpers/align_strategy.dart | 48 ++++++++++++++++++- 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index faac8c7b..bd0a09da 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -57,35 +57,3 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { return stack; } } - -class PositionedAlignment extends AlignStrategy { - /// Do we need to subtract some sort of offset? Maybe child.topLeftCorner.x - topLeftCorner.x? - - @override - void align(PBContext context, PBIntermediateStackLayout node) { - var alignedChildren = []; - node.children.skipWhile((child) { - /// if they are the same size then there is no need for adjusting. - if (child.topLeftCorner == node.topLeftCorner && - child.bottomRightCorner == node.bottomRightCorner) { - alignedChildren.add(child); - return true; - } - return false; - }).forEach((child) { - alignedChildren.add(InjectedPositioned(Uuid().v4(), - child.topLeftCorner.clone(), child.bottomRightCorner.clone(), - constraints: child.constraints, - currentContext: context, - valueHolder: PositionedValueHolder( - top: child.topLeftCorner.y - node.topLeftCorner.y, - bottom: node.bottomRightCorner.y - child.bottomRightCorner.y, - left: child.topLeftCorner.x - node.topLeftCorner.x, - right: node.bottomRightCorner.x - child.bottomRightCorner.x, - width: child.width, - height: child.height)) - ..addChild(child)); - }); - node.replaceChildren(alignedChildren); - } -} diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 9db48f3e..51ed0b47 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -145,9 +145,6 @@ abstract class PBIntermediateNode extends TraversableNode { return true; } - /// These are the constrains that are going to be used by the sub tree. - void _setSubTreeConstrains(PBIntermediateConstraints constraints) {} - /// Adds child to node. void addChild(node) { childrenStrategy.addChild(this, node); diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index abea1f12..60bf38de 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -1,9 +1,21 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:uuid/uuid.dart'; abstract class AlignStrategy{ void align(PBContext context, T node); + + void _setConstraints(PBContext context, T node){ + if(node.constraints.fixedHeight != null){ + context.contextConstraints.fixedHeight = node.constraints.fixedHeight; + } + if(node.constraints.fixedWidth != null){ + context.contextConstraints.fixedWidth = node.constraints.fixedWidth; + } + } } class PaddingAlignment extends AlignStrategy{ @@ -19,12 +31,46 @@ class PaddingAlignment extends AlignStrategy{ currentContext: node.currentContext); padding.addChild(node.child); node.child = padding; + super._setConstraints(context, node); } } class NoAlignment extends AlignStrategy{ @override void align(PBContext context, PBIntermediateNode node) { - + super._setConstraints(context, node); + } +} + +class PositionedAlignment extends AlignStrategy { + /// Do we need to subtract some sort of offset? Maybe child.topLeftCorner.x - topLeftCorner.x? + + @override + void align(PBContext context, PBIntermediateStackLayout node) { + var alignedChildren = []; + node.children.skipWhile((child) { + /// if they are the same size then there is no need for adjusting. + if (child.topLeftCorner == node.topLeftCorner && + child.bottomRightCorner == node.bottomRightCorner) { + alignedChildren.add(child); + return true; + } + return false; + }).forEach((child) { + alignedChildren.add(InjectedPositioned(Uuid().v4(), + child.topLeftCorner.clone(), child.bottomRightCorner.clone(), + constraints: child.constraints, + currentContext: context, + valueHolder: PositionedValueHolder( + top: child.topLeftCorner.y - node.topLeftCorner.y, + bottom: node.bottomRightCorner.y - child.bottomRightCorner.y, + left: child.topLeftCorner.x - node.topLeftCorner.x, + right: node.bottomRightCorner.x - child.bottomRightCorner.x, + width: child.width, + height: child.height)) + ..addChild(child)); + }); + node.replaceChildren(alignedChildren); + super._setConstraints(context, node); } } \ No newline at end of file From 59d013acd813554528ca223edc31265fe8396dbc Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Tue, 27 Jul 2021 08:52:58 -0500 Subject: [PATCH 263/404] Added Constraint Merging for Groups & fixed position gen for getPositionalAtt --- lib/design_logic/group_node.dart | 14 +++-- .../attribute-helper/pb_size_helper.dart | 4 -- .../visual-widgets/pb_positioned_gen.dart | 31 ++++++---- lib/input/figma/entities/layers/group.dart | 12 +++- lib/input/sketch/entities/layers/group.dart | 10 ++- .../entities/inherited_scaffold.dart | 42 ++++++------- .../rules/container_constraint_rule.dart | 3 +- .../entities/layouts/stack.dart | 13 ++-- .../layouts/temp_group_layout_node.dart | 5 +- .../pb_intermediate_constraints.dart | 61 ++++++++++++++++--- .../subclasses/pb_intermediate_node.dart | 11 ++-- .../pb_layout_intermediate_node.dart | 10 ++- .../entities/subclasses/pbdl_constraints.dart | 2 +- .../pb_constraint_generation_service.dart | 55 ++++------------- .../pb_layout_generation_service.dart | 20 +++++- 15 files changed, 171 insertions(+), 122 deletions(-) diff --git a/lib/design_logic/group_node.dart b/lib/design_logic/group_node.dart index a5957016..cabda6d5 100644 --- a/lib/design_logic/group_node.dart +++ b/lib/design_logic/group_node.dart @@ -115,11 +115,15 @@ class GroupNode implements DesignNodeFactory, DesignNode { @override Future interpretNode(PBContext currentContext) => - Future.value(TempGroupLayoutNode(this, currentContext, name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point( - boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height))); + Future.value(TempGroupLayoutNode( + this, + currentContext, + name, + topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), + bottomRightCorner: Point( + boundaryRectangle.x + boundaryRectangle.width, + boundaryRectangle.y + boundaryRectangle.height), + )); @override toJson() { diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index 00b48a6d..7e6d82fe 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -40,10 +40,6 @@ class PBSizeHelper extends PBAttributesHelper { ? relativeWidth / screenWidth : relativeWidth; - if (source.currentContext.tree.first.name == 'ArtboardBRpinfixedwidth') { - print('asdf'); - } - if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { var height = source.constraints.fixedHeight != null ? body['height'].toStringAsFixed(3) diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 5737e3e3..8d7695eb 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -25,6 +25,10 @@ class PBPositionedGenerator extends PBGenerator { var xAxisBoilerplate = boilerplate.item1; var yAxisBoilerplate = boilerplate.item2; + if (generatorContext.tree.first.name == 'ArtboardTRpinnoscale') { + print('asdf'); + } + /// Since the generation phase is going to run multiple times, we are going to have to /// create a copy/clone of the [PositionedValueHolder] instead of assigning the values /// directly to the [source.valueHolder]. This would causse the [source.valueHolder.getRatioPercentage] @@ -111,12 +115,13 @@ class PBPositionedGenerator extends PBGenerator { /// MediaQuery.of(context).size.height * 0.0 /// ``` /// Where it should be `0`. - String _normalizeValue(String preValueStatement, _PositionedValue positionalValue) { + String _normalizeValue( + String preValueStatement, _PositionedValue positionalValue) { var n = double.parse(positionalValue.value.toStringAsFixed(3)); if (n == 0) { return '0'; } - if(positionalValue.remainPointValue){ + if (positionalValue.remainPointValue) { return '$n'; } return '$preValueStatement$n'; @@ -124,29 +129,29 @@ class PBPositionedGenerator extends PBGenerator { List<_PositionedValue> _getPositionalAtt( PositionedValueHolder positionedValueHolder, - PBIntermediateConstraints constrains) { + PBIntermediateConstraints constraints) { var attributes = <_PositionedValue>[]; - var fixedWidth = constrains.fixedWidth != null; - var fixedHeight = constrains.fixedHeight != null; - if (!(constrains.pinLeft && constrains.pinRight)) { + var fixedWidth = constraints.fixedWidth != null; + var fixedHeight = constraints.fixedHeight != null; + if (!constraints.pinLeft && !constraints.pinRight) { ///use [positionedValueHolder.left] attributes .add(_PositionedValue(positionedValueHolder.left, 'left', false)); attributes.add( _PositionedValue(positionedValueHolder.width, 'width', fixedWidth)); - } else if (constrains.pinLeft && !constrains.pinRight) { + } else if (constraints.pinLeft && !constraints.pinRight) { ///use [positionedValueHolder.left] attributes .add(_PositionedValue(positionedValueHolder.left, 'left', true)); attributes.add( _PositionedValue(positionedValueHolder.width, 'width', fixedWidth)); - } else if (!constrains.pinLeft && constrains.pinRight) { + } else if (!constraints.pinLeft && constraints.pinRight) { /// use [positionedValueHolder.right] attributes .add(_PositionedValue(positionedValueHolder.right, 'right', true)); attributes.add( _PositionedValue(positionedValueHolder.width, 'width', fixedWidth)); - } else if (constrains.pinLeft && constrains.pinRight) { + } else if (constraints.pinLeft && constraints.pinRight) { attributes .add(_PositionedValue(positionedValueHolder.left, 'left', true)); attributes @@ -154,23 +159,23 @@ class PBPositionedGenerator extends PBGenerator { } ///Vertical constrains - if (!(constrains.pinTop && constrains.pinBottom)) { + if (!constraints.pinTop && !constraints.pinBottom) { attributes.add( _PositionedValue(positionedValueHolder.top, 'top', false, false)); attributes.add(_PositionedValue( positionedValueHolder.height, 'height', fixedHeight, false)); - } else if (constrains.pinTop && !constrains.pinBottom) { + } else if (constraints.pinTop && !constraints.pinBottom) { attributes .add(_PositionedValue(positionedValueHolder.top, 'top', true, false)); attributes.add(_PositionedValue( positionedValueHolder.height, 'height', fixedHeight, false)); - } else if (!constrains.pinTop && constrains.pinBottom) { + } else if (!constraints.pinTop && constraints.pinBottom) { /// use [positionedValueHolder.right] attributes.add(_PositionedValue( positionedValueHolder.bottom, 'bottom', true, false)); attributes.add(_PositionedValue( positionedValueHolder.height, 'height', fixedHeight, false)); - } else if (constrains.pinTop && constrains.pinBottom) { + } else if (constraints.pinTop && constraints.pinBottom) { attributes .add(_PositionedValue(positionedValueHolder.top, 'top', true, false)); attributes.add(_PositionedValue( diff --git a/lib/input/figma/entities/layers/group.dart b/lib/input/figma/entities/layers/group.dart index c3dd9b5a..9835f5b7 100644 --- a/lib/input/figma/entities/layers/group.dart +++ b/lib/input/figma/entities/layers/group.dart @@ -124,15 +124,21 @@ class Group extends FigmaFrame implements AbstractFigmaNodeFactory, Image { boundaryRectangle.width)), ); } - return Future.value(TempGroupLayoutNode( + var t = Future.value(TempGroupLayoutNode( this, currentContext, name, topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point(boundaryRectangle.x + boundaryRectangle.width, + bottomRightCorner: Point( + boundaryRectangle.x + boundaryRectangle.width, boundaryRectangle.y + boundaryRectangle.height), - constraints: convertFigmaConstraintToPBDLConstraint(constraints), + constraints: PBIntermediateConstraints.fromConstraints( + convertFigmaConstraintToPBDLConstraint(constraints), + boundaryRectangle.height, + boundaryRectangle.width), )); + // print(await t.then((value) => value.constraints)); + return t; } bool areAllVectors() { diff --git a/lib/input/sketch/entities/layers/group.dart b/lib/input/sketch/entities/layers/group.dart index f432c62d..46ac8fcc 100644 --- a/lib/input/sketch/entities/layers/group.dart +++ b/lib/input/sketch/entities/layers/group.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; import 'package:parabeac_core/input/sketch/entities/style/style.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -118,12 +119,15 @@ class Group extends AbstractGroupLayer implements SketchNodeFactory { @override Future interpretNode(PBContext currentContext) => Future.value(TempGroupLayoutNode(this, currentContext, name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), + topLeftCorner: + Point(boundaryRectangle.x, boundaryRectangle.y), bottomRightCorner: Point( boundaryRectangle.x + boundaryRectangle.width, boundaryRectangle.y + boundaryRectangle.height), - constraints: - convertSketchConstraintToPBDLConstraint(resizingConstraint))); + constraints: PBIntermediateConstraints.fromConstraints( + convertSketchConstraintToPBDLConstraint(resizingConstraint), + boundaryRectangle.height, + boundaryRectangle.width))); @override Map toPBDF() => { diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 5ac5ea7e..d511c976 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -10,11 +10,11 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - import 'interfaces/pb_inherited_intermediate.dart'; class InheritedScaffold extends PBVisualIntermediateNode @@ -84,12 +84,16 @@ class InheritedScaffold extends PBVisualIntermediateNode } @override - void addChild( node) { + void addChild(node) { + print(this.name); + if (this.name == 'ArtboardTRpinnoscale') { + print('object'); + } if (node is PBSharedInstanceIntermediateNode) { if (node.originalRef.name.contains('')) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); - currentContext.canvasTLC = Point(currentContext.canvasTLC.x, - node.bottomRightCorner.y); + currentContext.canvasTLC = + Point(currentContext.canvasTLC.x, node.bottomRightCorner.y); return; } if (node.originalRef.name.contains('')) { @@ -101,8 +105,8 @@ class InheritedScaffold extends PBVisualIntermediateNode if (node is InjectedAppbar) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); - currentContext.canvasTLC = Point(currentContext.canvasTLC.x, - node.bottomRightCorner.y); + currentContext.canvasTLC = + Point(currentContext.canvasTLC.x, node.bottomRightCorner.y); return; } if (node is InjectedTabBar) { @@ -117,10 +121,13 @@ class InheritedScaffold extends PBVisualIntermediateNode if (child != null) { child.addChild(node); } else { - var stack = PBIntermediateStackLayout( - currentContext, - name: node.name - ); + var stack = PBIntermediateStackLayout(currentContext, + name: node.name, + constraints: PBIntermediateConstraints( + pinBottom: false, + pinLeft: false, + pinRight: false, + pinTop: false)); stack.addChild(node); child = stack; } @@ -128,18 +135,5 @@ class InheritedScaffold extends PBVisualIntermediateNode } @override - void alignChild() { - if (child != null) { - // var padding = Padding('', child.constraints, - // left: (child.topLeftCorner.x - topLeftCorner.x).abs(), - // right: (bottomRightCorner.x - child.bottomRightCorner.x).abs(), - // top: (child.topLeftCorner.y - topLeftCorner.y).abs(), - // bottom: (bottomRightCorner.y - child.bottomRightCorner.y).abs(), - // topLeftCorner: topLeftCorner, - // bottomRightCorner: bottomRightCorner, - // currentContext: currentContext); - // padding.addChild(child); - // child = padding; - } - } + void alignChild() {} } diff --git a/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart index c4ba48f4..5b128d14 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart @@ -11,7 +11,8 @@ class ContainerConstraintRule extends PostConditionRule { if (testRule(currentNode, nextNode)) { var container = InjectedContainer(currentNode.bottomRightCorner, currentNode.topLeftCorner, currentNode.name, Uuid().v4(), - currentContext: currentNode.currentContext); + currentContext: currentNode.currentContext, + constraints: currentNode.constraints); container.addChild(currentNode); return container; } diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 226a32fc..92ee7231 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -19,8 +20,9 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { @override PrototypeNode prototypeNode; - PBIntermediateStackLayout(PBContext currentContext, {String name}) - : super(STACK_RULES, [], currentContext, name) { + PBIntermediateStackLayout(PBContext currentContext, + {String name, PBIntermediateConstraints constraints}) + : super(STACK_RULES, [], currentContext, name, constraints: constraints) { generator = PBStackGenerator(); } @@ -46,6 +48,9 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { /// Do we need to subtract some sort of offset? Maybe child.topLeftCorner.x - topLeftCorner.x? @override void alignChildren() { + if (this.currentContext.tree.first.name == 'ArtboardTRpinnoscale') { + print('asdf'); + } var alignedChildren = []; for (var child in children) { if (child.topLeftCorner == topLeftCorner && @@ -63,8 +68,8 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { left = child.topLeftCorner.x - topLeftCorner.x; right = bottomRightCorner.x - child.bottomRightCorner.x; - alignedChildren.add(InjectedPositioned( - Uuid().v4(), child.topLeftCorner.clone(), child.bottomRightCorner.clone(), + alignedChildren.add(InjectedPositioned(Uuid().v4(), + child.topLeftCorner.clone(), child.bottomRightCorner.clone(), valueHolder: PositionedValueHolder( top: top, bottom: bottom, diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index 31e1d0d4..d29f3c3b 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; @@ -15,8 +16,8 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode PrototypeNode prototypeNode; TempGroupLayoutNode(this.originalRef, PBContext currentContext, String name, - {topLeftCorner, bottomRightCorner, PBDLConstraints constraints}) - : super([], [], currentContext, name) { + {topLeftCorner, bottomRightCorner, PBIntermediateConstraints constraints}) + : super([], [], currentContext, name, constraints: constraints) { if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart index c674c8f3..374038dc 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart @@ -1,9 +1,22 @@ +import 'dart:developer'; + import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; /// Named PBDL in anticipation of the refactor where PBDL becomes the design standard. /// Each property must be set. /// TODO: Use https://pub.dev/packages/meta to make these named parameters required. class PBIntermediateConstraints { + bool pinLeft; + bool pinRight; + bool pinTop; + bool pinBottom; + + /// If value is null, then the height is not fixed. + double fixedHeight; + + /// If value is null, then the width is not fixed. + double fixedWidth; + PBIntermediateConstraints( {this.pinLeft, this.pinRight, @@ -25,14 +38,46 @@ class PBIntermediateConstraints { fixedWidth = width; } } - bool pinLeft; - bool pinRight; - bool pinTop; - bool pinBottom; - /// If value is null, then the height is not fixed. - double fixedHeight; + PBIntermediateConstraints.mergeFromContraints( + PBIntermediateConstraints first, PBIntermediateConstraints second) { + pinTop = (first.pinTop || second.pinTop) ? true : false; + pinLeft = (first.pinLeft || second.pinLeft) ? true : false; + pinRight = (first.pinRight || second.pinRight) ? true : false; + pinBottom = (first.pinBottom || second.pinBottom) ? true : false; - /// If value is null, then the width is not fixed. - double fixedWidth; + /// Set Fixed Height Value + if (first.fixedHeight != null || second.fixedHeight != null) { + if (first.fixedHeight != null && second.fixedHeight != null) { + if (first.fixedHeight != second.fixedHeight) { + log('PBIntermediatConstraints tried merging constraints where fixed height & fixed height were both set & not equal.'); + fixedHeight = first.fixedHeight; + } else { + fixedHeight = first.fixedHeight; + } + } + if (first.fixedHeight == null) { + fixedHeight = second.fixedHeight; + } else { + fixedHeight = first.fixedHeight; + } + } + + /// Set Fixed Width Value + if (first.fixedWidth != null || second.fixedWidth != null) { + if (first.fixedWidth != null && second.fixedWidth != null) { + if (first.fixedWidth != second.fixedWidth) { + log('PBIntermediatConstraints tried merging constraints where fixed width & fixed width were both set & not equal.'); + fixedWidth = first.fixedHeight; + } else { + fixedWidth = first.fixedHeight; + } + } + if (first.fixedWidth == null) { + fixedWidth = second.fixedWidth; + } else { + fixedWidth = first.fixedWidth; + } + } + } } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 26446a2f..51c213b3 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -57,7 +57,7 @@ abstract class PBIntermediateNode extends TraversableNode { Point topLeftCorner; Point bottomRightCorner; - + double get width => (bottomRightCorner.x - topLeftCorner.x).toDouble(); double get height => (bottomRightCorner.y - topLeftCorner.y).toDouble(); @@ -142,11 +142,12 @@ abstract class PBIntermediateNode extends TraversableNode { } /// Adds child to node. - void addChild(node){ + void addChild(node) { childrenStrategy.addChild(this, node); } } -extension PBPointLegacyMethod on Point{ + +extension PBPointLegacyMethod on Point { Point clone() => Point(x, y); // TODO: This is a temporal fix ----- Not sure why there some sort of safe area for the y-axis?? @@ -155,7 +156,7 @@ extension PBPointLegacyMethod on Point{ y == anotherPoint.y || (y.abs() - anotherPoint.y.abs()).abs() < 3 ? x.compareTo(anotherPoint.x) : y.compareTo(anotherPoint.y); - + bool operator <(Object point) { if (point is Point) { return y == point.y ? x <= point.x : y <= point.y; @@ -169,4 +170,4 @@ extension PBPointLegacyMethod on Point{ } return false; } -} \ No newline at end of file +} diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index 87949488..8e1075a8 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prot import 'package:parabeac_core/interpret_and_optimize/entities/layouts/exceptions/layout_exception.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:uuid/uuid.dart'; @@ -37,9 +38,12 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode PBLayoutIntermediateNode(this._layoutRules, this._exceptions, PBContext currentContext, String name, - {topLeftCorner, bottomRightCorner, this.prototypeNode}) + {topLeftCorner, + bottomRightCorner, + this.prototypeNode, + PBIntermediateConstraints constraints}) : super(topLeftCorner, bottomRightCorner, Uuid().v4(), name, - currentContext: currentContext) { + currentContext: currentContext, constraints: constraints) { // Declaring children for layout node addAttribute(PBAttribute('children')); } @@ -170,4 +174,4 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode } } } -} \ No newline at end of file +} diff --git a/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart index d321d643..ed75488f 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart @@ -8,6 +8,7 @@ class PBDLConstraints { this.pinBottom, this.fixedHeight, this.fixedWidth}); + /// - If all the pins are `false` thats just means is going to scale normally. /// - If there is a pin value that is `true` we are going to use the constant value for that /// attribute instead of the scaling value(using media query). @@ -16,7 +17,6 @@ class PBDLConstraints { bool pinTop; bool pinBottom; - bool fixedHeight; bool fixedWidth; } diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index 6846d391..c3c607bf 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -11,59 +11,22 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_serv ///tree.where((element) => element != null).toList().reversed.map((e) => e.name).toList() class PBConstraintGenerationService implements AITHandler { - PBConstraintGenerationService(); /// Traverse to the bottom of the tree, and implement constraints to nodes that don't already contain it such as [InjectedContainer] and then work our way up the tree. /// Through Traversal, discover whether there are elements that will conflict on scaling, if so, change the layout to a Stack. - Future implementConstraints(PBIntermediateTree tree, PBContext context) { + Future implementConstraints( + PBIntermediateTree tree, PBContext context) { if (tree.rootNode == null) { return Future.value(tree); } for (var node in tree.where((element) => element != null).toList().reversed) { - if (node is PBLayoutIntermediateNode) { - // if (node.children.isNotEmpty) { - /// Inherit Constraints from all the children of this layout. - node.children - .where((element) => element != null) - .toList() - .forEach((element) { - node.constraints = _inheritConstraintsFromChild( - constraints: node.constraints ?? - PBIntermediateConstraints( - pinTop: false, - pinBottom: false, - pinLeft: false, - pinRight: false, - ), - childConstraints: element.constraints); - }); - if (node is PBLayoutIntermediateNode) { - if (_shouldLayoutBeStack(node)) { - /// Change Layout to Stack - var newStackReplacement = - PBIntermediateStackLayout(context, name: node.name); - node.attributes.forEach((element) { - newStackReplacement.addAttribute(element); - }); - newStackReplacement.constraints = node.constraints; - node = newStackReplacement; - } - } - } if (node.constraints == null) { if (node.child?.constraints == null) { - // if (node.child != null) { - print( - "Constraint Inheritance could not be performed because child's constraints were null for class type: [${node.runtimeType}]"); - // } - if (node is! InheritedText) { - print('asdf'); - } else { - node.constraints = PBIntermediateConstraints(); - } + node.constraints = PBIntermediateConstraints( + pinBottom: false, pinLeft: false, pinRight: false, pinTop: false); } else { node.constraints = node.child.constraints; } @@ -73,6 +36,7 @@ class PBConstraintGenerationService implements AITHandler { } /// Go through children and find out if there's a node that will overlap another node when scaling. + /// @deprecated - remove with PR to dev/stable. bool _shouldLayoutBeStack(PBLayoutIntermediateNode node) { if (node is PBIntermediateStackLayout) { return false; @@ -91,6 +55,7 @@ class PBConstraintGenerationService implements AITHandler { } } + /// @deprecated - remove with PR to dev/stable. bool _isHorizontalOverlap(PBLayoutIntermediateNode node) { var lastLeftPinIndex = -1; var lastRightPinIndex = -1; @@ -122,6 +87,7 @@ class PBConstraintGenerationService implements AITHandler { return isOverlap; } + /// @deprecated - remove with PR to dev/stable. bool _isVerticalOverlap(PBLayoutIntermediateNode node) { var lastTopPinIndex = -1; var lastBottomPinIndex = -1; @@ -152,6 +118,7 @@ class PBConstraintGenerationService implements AITHandler { return isOverlap; } + /// @deprecated - remove with PR to dev/stable. PBIntermediateConstraints _inheritConstraintsFromChild( {PBIntermediateConstraints constraints, PBIntermediateConstraints childConstraints}) { @@ -185,8 +152,8 @@ class PBConstraintGenerationService implements AITHandler { } @override - Future handleTree(PBContext context, PBIntermediateTree tree) { - return implementConstraints(tree, context); - + Future handleTree( + PBContext context, PBIntermediateTree tree) { + return implementConstraints(tree, context); } } diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index e79a18f5..9e148e15 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/stac import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; @@ -47,7 +48,7 @@ class PBLayoutGenerationService implements AITHandler { // currentContext: currentContext), 'stack': PBIntermediateStackLayout( null, - ), + ), }; for (var layoutType @@ -73,7 +74,7 @@ class PBLayoutGenerationService implements AITHandler { // .map((node) => _layoutConditionalReplacement(node, context)) // .toList() // ..removeWhere((element) => element == null)) - // .first; + // .first; rootNode = _traverseLayersUtil(rootNode, (layer) { return layer @@ -242,6 +243,21 @@ class PBLayoutGenerationService implements AITHandler { PBIntermediateNode candidate, PBIntermediateNode replacement) { if (candidate is PBLayoutIntermediateNode && replacement is PBLayoutIntermediateNode) { + /// For supporting pinning & resizing information, we will merge constraints. + print(replacement.constraints); + replacement.constraints = PBIntermediateConstraints.mergeFromContraints( + candidate.constraints ?? + PBIntermediateConstraints( + pinBottom: false, + pinLeft: false, + pinRight: false, + pinTop: false), + replacement.constraints ?? + PBIntermediateConstraints( + pinBottom: false, + pinLeft: false, + pinRight: false, + pinTop: false)); replacement.prototypeNode = candidate.prototypeNode; } return replacement; From fc5a7f93f40f3df3c4ca2e490e8b6db2a18f384b Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 27 Jul 2021 17:56:46 -0600 Subject: [PATCH 264/404] WIP ADDED the unit test for inherited constraints and CREATED a [PBIntermediateTree] builder for easier testing of the tree. --- .../dfs_iterator_test.dart | 84 ++++++++---- .../pb_align_generation_service_test.dart | 120 ++++++++++-------- 2 files changed, 128 insertions(+), 76 deletions(-) diff --git a/test/lib/interpret_and_optimize/dfs_iterator_test.dart b/test/lib/interpret_and_optimize/dfs_iterator_test.dart index 0e32b59f..4fa37225 100644 --- a/test/lib/interpret_and_optimize/dfs_iterator_test.dart +++ b/test/lib/interpret_and_optimize/dfs_iterator_test.dart @@ -5,49 +5,81 @@ import 'package:mockito/mockito.dart'; class MockContainer extends Mock implements PBIntermediateNode {} +class TreeBuilder { + num numberOfContainers; + List _containerList; + T rootNode; + + var nodeBuilder; + var rootNodeBuilder; + + TreeBuilder(this.numberOfContainers, + {T Function(int index) this.nodeBuilder, + T Function(List children) this.rootNodeBuilder}) { + nodeBuilder ??= _mockContainerBuilder; + rootNodeBuilder ??= _rootNodeBuilder; + } + + T _mockContainerBuilder(int idx) { + var container = MockContainer(); + + var containerChild = MockContainer(); + when(containerChild.UUID).thenReturn(('C_$idx')); + + when(container.children).thenReturn([containerChild]); + when(container.UUID).thenReturn('P_$idx'); + return container as T; + } + + T _rootNodeBuilder(List children) { + var rootNode = MockContainer(); + when(rootNode.UUID).thenReturn('R_123'); + when(rootNode.children).thenReturn(_containerList); + return rootNode as T; + } + + PBIntermediateTree build() { + _containerList = List.generate((numberOfContainers ~/ 2), nodeBuilder); + rootNode = rootNodeBuilder(_containerList); + + var tree = PBIntermediateTree('Example'); + tree.rootNode = rootNode; + + ///Taking into account the [rootNode] + numberOfContainers++; + return tree; + } +} + void main() { - var containerList; var numberOfContainers; var rootNode; + TreeBuilder treeBuilder; PBIntermediateTree tree; group('Testing the PBIntermediateTree', () { setUp(() { ///This is the tree that is going to be build: - /// R_123 + /// [R_123] /// | /// [P_0, P_1, P_2, P_3, P_4] /// | | | | | /// [C_0][C_1][C_2][C_3][C_4] - - numberOfContainers = 10; - containerList = List.generate((numberOfContainers ~/ 2), (idx) { - var container = MockContainer(); - - var containerChild = MockContainer(); - when(containerChild.UUID).thenReturn(('C_$idx')); - - when(container.children).thenReturn([containerChild]); - when(container.UUID).thenReturn('P_$idx'); - return container; - }); + /// - rootNode = MockContainer(); - when(rootNode.UUID).thenReturn('R_123'); - when(rootNode.children).thenReturn(containerList); - - tree = PBIntermediateTree('Example'); - tree.rootNode = rootNode; - - ///Taking into account the [rootNode] - numberOfContainers++; + numberOfContainers = 10; + treeBuilder = TreeBuilder(numberOfContainers); + tree = treeBuilder.build(); + rootNode = treeBuilder.rootNode; }); test('Testing the traversal of the IntermediateTree', () { - expect(tree.length, numberOfContainers); + expect(tree.length, treeBuilder.numberOfContainers); expect(tree.first, rootNode); }); - test('Testing [PBIntermediateTree.dist] function, see if it gives the correct distance between two nodes', (){ + test( + 'Testing [PBIntermediateTree.dist] function, see if it gives the correct distance between two nodes', + () { var child = tree.firstWhere((node) => node.UUID == 'C_0'); expect(child, isNotNull); expect(tree.depthOf(child), 2); @@ -55,7 +87,7 @@ void main() { var parent = tree.firstWhere((node) => node.UUID == 'P_0'); expect(parent, isNotNull); expect(tree.depthOf(parent), 1); - + expect(rootNode, isNotNull); expect(tree.depthOf(rootNode), 0); }); diff --git a/test/lib/interpret_and_optimize/services/pb_align_generation_service_test.dart b/test/lib/interpret_and_optimize/services/pb_align_generation_service_test.dart index a1aea435..c85a9537 100644 --- a/test/lib/interpret_and_optimize/services/pb_align_generation_service_test.dart +++ b/test/lib/interpret_and_optimize/services/pb_align_generation_service_test.dart @@ -1,73 +1,93 @@ +import 'dart:math'; + import 'package:mockito/mockito.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; import 'package:test/test.dart'; import 'package:uuid/uuid.dart'; -class MockContext extends Mock implements PBContext { - @override - PBConfiguration configuration; - - @override - Map jsonConfigurations; +import '../dfs_iterator_test.dart'; - @override - Point screenBottomRightCorner; - - @override - Point screenTopLeftCorner; -} +class MockContext extends Mock implements PBContext {} class MockContainer extends Mock implements InjectedContainer {} +var containerList; +PBIntermediateTree tree; +PBAlignGenerationService alignGenerationService; +PBContext context; + void main() { group('Testing the Positions generated for stacks', () { PBIntermediateStackLayout stack; setUp(() { - stack = PBIntermediateStackLayout('Testing Stack', Uuid().v4(), - currentContext: MockContext()); + context = PBContext(null); + context.contextConstraints = PBIntermediateConstraints(); + + tree = TreeBuilder(10, nodeBuilder: (index) { + + /// Constructing the [PBIntermediateTree] with real [InjectedContainer] rather than + /// using the [Mock] + var origin = Point(0, 0); + var container = InjectedContainer( + origin, origin, 'P_$index', 'P_$index', + constraints: PBIntermediateConstraints()); + container.childrenStrategy = OneChildStrategy('child'); + + var containerChild = InjectedContainer( + origin, origin, 'C_$index', 'C_$index', + constraints: PBIntermediateConstraints()); + containerChild.childrenStrategy = OneChildStrategy('child'); + + container.addChild(containerChild); + return container; + }, rootNodeBuilder: (children) { + + /// Constructing a real [InjectedContainer] as [PBIntermediateTree.rootNode] rather + /// than using a [Mock] + var rootNode = PBIntermediateStackLayout(context); + rootNode.constraints = PBIntermediateConstraints(); + rootNode.alignStrategy = NoAlignment(); + + rootNode.replaceChildren(children); + return rootNode; + }).build(); + + context.tree = tree; + alignGenerationService = PBAlignGenerationService(); }); - test('Testing the stack alignment algorithm', () { - var isYPositive = true, isXPositive = true; - - stack.topLeftCorner = Point(-200, -200); - stack.bottomRightCorner = Point(200, 200); - var startingTLC = Point(100, 100), startingBTC = Point(150, 150); - - var containers = List.generate(4, (index) { - var mockContainer = MockContainer(); - when(mockContainer.topLeftCorner).thenReturn(Point( - isXPositive ? startingTLC.x : (startingTLC.x * -1), - (isYPositive ? startingTLC.y : startingTLC.y * -1))); - when(mockContainer.bottomRightCorner).thenReturn(Point( - isXPositive ? startingBTC.x : (startingBTC.x * -1), - (isYPositive ? startingBTC.y : startingBTC.y * -1))); - index % 2 == 0 - ? isYPositive = !isYPositive - : isXPositive = !isXPositive; - return mockContainer; - }).cast(); - - stack.replaceChildren(containers); - stack.alignChildren(); - containers = stack.children; - expect(containers.length, 4, reason: 'numbers of children change'); - - isXPositive = true; - isYPositive = true; - for (var i = 0; i < containers.length; i++) { - var container = containers[i]; - expect(container.runtimeType, InjectedPositioned, - reason: 'should be of type InjectedPositioned'); - - i % 2 == 0 ? isYPositive = !isYPositive : isXPositive = !isXPositive; - } + test( + 'When given a node contains contraints that are inheritable after [PBAlignGenerationService]', + () { + var inheritedFixedHeight = 2.0; + var inheritedFixedWidth = 3.0; + + var parent = tree.firstWhere((child) => child?.UUID == 'P_0'); + parent.constraints.fixedHeight = inheritedFixedHeight; + parent.constraints.fixedWidth = inheritedFixedWidth; + alignGenerationService.addAlignmentToLayouts(tree, context); + + var inheritedConstrainsChild = + tree.firstWhere((child) => child.UUID == 'C_0'); + var nonInheritedConstrainsChild = + tree.firstWhere((child) => child.UUID == 'C_1'); + + expect(inheritedConstrainsChild.constraints.fixedHeight, + inheritedFixedHeight); + expect( + inheritedConstrainsChild.constraints.fixedWidth, inheritedFixedWidth); + expect(nonInheritedConstrainsChild.constraints.fixedHeight, isNull); + expect(nonInheritedConstrainsChild.constraints.fixedWidth, isNull); }); }); } From 67473a42ddac1f3503270d4e7ee3039dbf51835e Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 27 Jul 2021 17:58:40 -0600 Subject: [PATCH 265/404] FIX the small pass by reference bug with the context passed to the [PBIntermediateTree], this involved CREATING a temp solution clone of the context that was being passed to each level of the tree. --- .../entities/layouts/stack.dart | 4 +- .../pb_intermediate_constraints.dart | 28 +++++++---- .../subclasses/pb_intermediate_node.dart | 15 +++++- .../helpers/align_strategy.dart | 48 ++++++++++++++----- .../helpers/pb_context.dart | 25 +++++++++- .../pb_alignment_generation_service.dart | 9 ++-- 6 files changed, 99 insertions(+), 30 deletions(-) diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index bd0a09da..cdd3ba5f 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -20,12 +20,10 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { @override PrototypeNode prototypeNode; - @override - AlignStrategy alignStrategy = PositionedAlignment(); - PBIntermediateStackLayout(PBContext currentContext, {String name}) : super(STACK_RULES, [], currentContext, name) { generator = PBStackGenerator(); + alignStrategy = PositionedAlignment(); } @override diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart index c674c8f3..c594eb55 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart @@ -4,6 +4,16 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_co /// Each property must be set. /// TODO: Use https://pub.dev/packages/meta to make these named parameters required. class PBIntermediateConstraints { + bool pinLeft; + bool pinRight; + bool pinTop; + bool pinBottom; + + /// If value is null, then the height is not fixed. + double fixedHeight; + + /// If value is null, then the width is not fixed. + double fixedWidth; PBIntermediateConstraints( {this.pinLeft, this.pinRight, @@ -25,14 +35,14 @@ class PBIntermediateConstraints { fixedWidth = width; } } - bool pinLeft; - bool pinRight; - bool pinTop; - bool pinBottom; - - /// If value is null, then the height is not fixed. - double fixedHeight; - /// If value is null, then the width is not fixed. - double fixedWidth; + PBIntermediateConstraints clone() { + return PBIntermediateConstraints( + pinBottom: pinBottom, + pinTop: pinTop, + pinRight: pinRight, + pinLeft: pinLeft, + fixedHeight: fixedHeight, + fixedWidth: fixedWidth); + } } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 51ed0b47..5251f216 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -39,7 +39,7 @@ abstract class PBIntermediateNode extends TraversableNode { List get children => [child]; ChildrenStrategy childrenStrategy = OneChildStrategy('child'); - + AlignStrategy alignStrategy = NoAlignment(); /// Gets the [PBIntermediateNode] at attribute `child` @@ -153,8 +153,21 @@ abstract class PBIntermediateNode extends TraversableNode { /// constrains could be inherited to that section of the sub-tree. } + /// In a recursive manner align the current [this] and the [children] of [this] + /// + /// Its creating a [PBContext.clone] because some values of the [context] are modified + /// when passed to some of the [children]. + /// For example, the [context.contextConstraints] might + /// could contain information from a parent to that particular section of the tree. However, + /// because its pass by reference that edits to the context are going to affect the entire [context.tree] and + /// not just the sub tree, therefore, we need to [PBContext.clone] to avoid those side effets. + /// + /// INFO: there might be a more straight fowards backtracking way of preventing these side effects. void align(PBContext context) { alignStrategy.align(context, this); + for (var child in children) { + child?.align(context.clone()); + } } } diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 60bf38de..26396e6a 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -1,31 +1,57 @@ import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:uuid/uuid.dart'; -abstract class AlignStrategy{ +/// [AlignStrategy] uses the strategy pattern to define the alignment logic for +/// the [PBIntermediateNode]. +abstract class AlignStrategy { void align(PBContext context, T node); - void _setConstraints(PBContext context, T node){ - if(node.constraints.fixedHeight != null){ - context.contextConstraints.fixedHeight = node.constraints.fixedHeight; + /// Some aspects of the [PBContext] are going to be inherited to a subtree + /// of the [PBIntermediateTree]. These are the [PBContext.fixedHeight] and + /// [PBContext.fixedWidth]. + /// + /// If the [context] contains either [context.fixedHeight] or [context.fixedHeight], + /// then its going to force those values into the [node]. However, if the [node] contains non-null + /// constrains and the [context] does not, then [context] is going to grab those values and force upon the children + /// from that subtree. + /// + /// Another important note is when the [context] contains [context.fixedHeight] the subtree, then we will + /// assign the [node.constraints.pinTop] = `true` and [node.constraints.pinBottom] = `false`. + /// When [context.fixedWidth] is not `null`, se assign the [context.fixedWidth] to subtree and + /// we make [node.constraints.pinLeft] = `true` and [node.constraints.pingRight] = `false`. + void _setConstraints(PBContext context, T node) { + context.contextConstraints.fixedHeight ??= node.constraints.fixedHeight; + context.contextConstraints.fixedWidth ??= node.constraints.fixedWidth; + + if (context.contextConstraints.fixedHeight != null) { + node.constraints.fixedHeight = context.contextConstraints.fixedHeight; + node.constraints.pinTop = true; + node.constraints.pinBottom = false; } - if(node.constraints.fixedWidth != null){ - context.contextConstraints.fixedWidth = node.constraints.fixedWidth; + + if (context.contextConstraints.fixedWidth != null) { + node.constraints.fixedWidth = context.contextConstraints.fixedWidth; + node.constraints.pinLeft = true; + node.constraints.pinRight = false; } } } -class PaddingAlignment extends AlignStrategy{ +class PaddingAlignment extends AlignStrategy { @override void align(PBContext context, PBIntermediateNode node) { var padding = Padding('', node.child.constraints, left: (node.child.topLeftCorner.x - node.topLeftCorner.x).abs(), - right: (node.bottomRightCorner.x - node.child.bottomRightCorner.x).abs(), + right: + (node.bottomRightCorner.x - node.child.bottomRightCorner.x).abs(), top: (node.child.topLeftCorner.y - node.topLeftCorner.y).abs(), - bottom: (node.child.bottomRightCorner.y - node.bottomRightCorner.y).abs(), + bottom: + (node.child.bottomRightCorner.y - node.bottomRightCorner.y).abs(), topLeftCorner: node.topLeftCorner, bottomRightCorner: node.bottomRightCorner, currentContext: node.currentContext); @@ -35,7 +61,7 @@ class PaddingAlignment extends AlignStrategy{ } } -class NoAlignment extends AlignStrategy{ +class NoAlignment extends AlignStrategy { @override void align(PBContext context, PBIntermediateNode node) { super._setConstraints(context, node); @@ -73,4 +99,4 @@ class PositionedAlignment extends AlignStrategy { node.replaceChildren(alignedChildren); super._setConstraints(context, node); } -} \ No newline at end of file +} diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 52d5ee96..c77b1860 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -44,7 +44,7 @@ class PBContext { Point canvasBRC; /// The [constextConstrains] represents the costraints that would be inherited by a section of the tree. - /// + /// /// For example, when there is a [InjectedPositioned] that contains [contextConstraints.fixedWidth], then /// all of the [InjectedPositioned.child] subtree should inherit that information. PBIntermediateConstraints contextConstraints = PBIntermediateConstraints(); @@ -59,7 +59,14 @@ class PBContext { PBGenerationViewData get managerData => tree?.data; - PBContext(this.configuration, {this.tree}); + PBContext(this.configuration, + {this.tree, + this.contextConstraints, + this.masterNode, + this.project, + this.canvasBRC, + this.canvasTLC, + this.generationManager}); void addDependent(PBIntermediateTree dependent) { if (dependent != null) { @@ -80,6 +87,20 @@ class PBContext { ? size / originalScreenWidth : size / originaScreenHeight; } + + PBContext clone() { + var context = PBContext(configuration, + tree: tree, + contextConstraints: contextConstraints.clone(), + masterNode: masterNode, + project: project, + canvasBRC: canvasBRC, + canvasTLC: canvasTLC, + generationManager: generationManager); + context.screenTopLeftCorner = _screenTLC; + context.screenBottomRightCorner = _screenBRC; + return context; + } } enum SizingValueContext { diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index d6671d46..bc40fab1 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -18,20 +18,21 @@ class PBAlignGenerationService implements AITHandler { } /// Should find all layout nodes - Future addAlignmentToLayouts(PBIntermediateTree tree, PBContext context) { + Future addAlignmentToLayouts( + PBIntermediateTree tree, PBContext context) { var originalRoot = tree.rootNode; if (originalRoot == null) { log.warning( '[PBAlignmentGenerationService] generate() attempted to generate a non-existing tree'); return null; } - - tree.forEach((node) => node?.align(context)); + tree.rootNode.align(context); return Future.value(tree); } @override - Future handleTree(PBContext context, PBIntermediateTree tree) { + Future handleTree( + PBContext context, PBIntermediateTree tree) { return addAlignmentToLayouts(tree, context); } } From 5de418d9ccaf606e28a957fdd5143a4189adcbd2 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 30 Jul 2021 17:06:01 -0600 Subject: [PATCH 266/404] WIP(Issue 474) CREATED the FileSystemAnalyzer class, reponsible checking the project's existance and indexing its files. --- .../file_system_analyzer.dart | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 lib/generation/flutter_project_builder/file_system_analyzer.dart diff --git a/lib/generation/flutter_project_builder/file_system_analyzer.dart b/lib/generation/flutter_project_builder/file_system_analyzer.dart new file mode 100644 index 00000000..8f6baca7 --- /dev/null +++ b/lib/generation/flutter_project_builder/file_system_analyzer.dart @@ -0,0 +1,88 @@ +import 'dart:io'; +import 'package:path/path.dart' as p; +import 'package:quick_log/quick_log.dart'; + +/// The [FileSystemAnalyser]'s main purpose is enable the continous modification +/// of dart files in a particular directory. +/// +/// This is done by keeping track of the [File]s that are within the [projectPath]. +/// These paths are going to be used by other components in Parabeac-Core to see if +/// those files should be replaced or non touched. +/// +/// Parabeac-Core is going to follow the convention of many code-generating packages, of +/// encapsulating their code changes in files with a `.g.dart` appended to their [File]. Furthermore, +/// Parabeac-Core also might generate some non`.g.dart`(e.g. `example.dart`) files the first time, +/// as boilerplate for the developer. +class FileSystemAnalyzer { + Logger _logger; + + /// A set that contains multiple paths + p.PathSet _pathSet; + + /// Path of where the project [Directory] is located. + String _projectPath; + String get projectPath => _projectPath; + + /// The actual [Directory] of [projectPath] + Directory _projectDir; + + /// Flag to see if project exist, mainly so we dont run [projectExist] multiple + /// times. + bool _projectChecked = false; + + FileSystemAnalyzer(String projectPath) { + assert(projectPath != null); + + _logger = Logger(runtimeType.toString()); + + _projectPath = p.normalize(projectPath); + _pathSet = p.PathSet(context: p.Context()); + } + + bool containsFile(String path){ + if(path == null){ + throw NullThrownError(); + } + return _pathSet.contains(p.normalize(path)); + } + + + + /// returns if a [Directory] is present on the path of [_projectPath] + Future projectExist() { + return FileSystemEntity.type(_projectPath, followLinks: false) + .then((FileSystemEntityType type) { + _projectChecked = true; + if (type is Directory) { + _projectDir = Directory(_projectPath); + return true; + } + _logger.info( + 'The $_projectPath does not exist or its not of type Directory (actual type: ${type.toString()})'); + return false; + }); + } + + /// From the [_projectPath] provided, we are going to scan all the files within and + /// save them in [_pathSet] + Future indexProjectFiles() async { + if (!_projectChecked) { + await projectExist(); + } + if (_projectDir == null) { + throw FileSystemException('There is no project directory present'); + } + + /// Traverse the files of the directory + _logger.info('Indexing files within $projectPath...'); + var filePaths = await _projectDir + .list(recursive: true, followLinks: false) + .where((entity) => entity is File) + .cast() + .map((File file) => p.normalize(file.path)) + .toList(); + _logger.info('Completed indexing files'); + + _pathSet.addAll(filePaths); + } +} From 3ebb93caa33ee0c8681d69513d89901ba809015e Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 30 Jul 2021 17:26:45 -0600 Subject: [PATCH 267/404] WIP(Issue 474) Had to expose FileSystem object to create unit test by sending a MemoryFileSystem (recommended by file package) --- .../file_system_analyzer.dart | 32 +++++++++++++++---- pubspec.yaml | 1 + 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/generation/flutter_project_builder/file_system_analyzer.dart b/lib/generation/flutter_project_builder/file_system_analyzer.dart index 8f6baca7..f0229fe9 100644 --- a/lib/generation/flutter_project_builder/file_system_analyzer.dart +++ b/lib/generation/flutter_project_builder/file_system_analyzer.dart @@ -1,5 +1,7 @@ -import 'dart:io'; +// import 'dart:io'; +import 'package:file/local.dart'; import 'package:path/path.dart' as p; +import 'package:file/file.dart'; import 'package:quick_log/quick_log.dart'; /// The [FileSystemAnalyser]'s main purpose is enable the continous modification @@ -16,6 +18,10 @@ import 'package:quick_log/quick_log.dart'; class FileSystemAnalyzer { Logger _logger; + /// Had to expose use the `file` dart package and expose the + /// [FileSystem] in order to perform some testing in the [FileSystemAnalyzer]. + FileSystem fileSystem; + /// A set that contains multiple paths p.PathSet _pathSet; @@ -30,10 +36,11 @@ class FileSystemAnalyzer { /// times. bool _projectChecked = false; - FileSystemAnalyzer(String projectPath) { + FileSystemAnalyzer(String projectPath, {this.fileSystem}) { assert(projectPath != null); _logger = Logger(runtimeType.toString()); + fileSystem ??= LocalFileSystem(); _projectPath = p.normalize(projectPath); _pathSet = p.PathSet(context: p.Context()); @@ -50,15 +57,26 @@ class FileSystemAnalyzer { /// returns if a [Directory] is present on the path of [_projectPath] Future projectExist() { - return FileSystemEntity.type(_projectPath, followLinks: false) + return fileSystem.isDirectory(_projectPath) + .then((isDirectory) { + _projectChecked = true; + if(isDirectory){ + _projectDir = fileSystem.directory(_projectPath); + } + else{ + _logger.info( + 'The $_projectPath does not exist or its not of type Directory.'); + } + return isDirectory; + }); + return fileSystem.type(_projectPath, followLinks: false) .then((FileSystemEntityType type) { _projectChecked = true; - if (type is Directory) { - _projectDir = Directory(_projectPath); + if (fileSystem.isDirectorySync(path)) { + _projectDir = fileSystem.directory(_projectPath); return true; } - _logger.info( - 'The $_projectPath does not exist or its not of type Directory (actual type: ${type.toString()})'); + return false; }); } diff --git a/pubspec.yaml b/pubspec.yaml index 5ec63de9..2c6673dc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,7 @@ dependencies: tuple: ^1.0.3 azblob: ^1.0.3 path: ^1.6.0 + file: ^6.1.2 dev_dependencies: pedantic: ^1.8.0 From debe3523b1fb94c5d4a189931dea4f5fa783a7aa Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 30 Jul 2021 21:11:04 -0600 Subject: [PATCH 268/404] WIP(Issue 474) CREATED unit test that verifies the functionality of FileSystemAnalyzer working (looking if the project exist & indexing files). --- .../file_system_analyzer.dart | 28 ++------ .../generation/file_system_analyzer_test.dart | 66 +++++++++++++++++++ 2 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 test/lib/generation/file_system_analyzer_test.dart diff --git a/lib/generation/flutter_project_builder/file_system_analyzer.dart b/lib/generation/flutter_project_builder/file_system_analyzer.dart index f0229fe9..66d2c540 100644 --- a/lib/generation/flutter_project_builder/file_system_analyzer.dart +++ b/lib/generation/flutter_project_builder/file_system_analyzer.dart @@ -1,4 +1,3 @@ -// import 'dart:io'; import 'package:file/local.dart'; import 'package:path/path.dart' as p; import 'package:file/file.dart'; @@ -24,6 +23,7 @@ class FileSystemAnalyzer { /// A set that contains multiple paths p.PathSet _pathSet; + List get paths => _pathSet.toList(); /// Path of where the project [Directory] is located. String _projectPath; @@ -46,39 +46,25 @@ class FileSystemAnalyzer { _pathSet = p.PathSet(context: p.Context()); } - bool containsFile(String path){ - if(path == null){ + bool containsFile(String path) { + if (path == null) { throw NullThrownError(); } return _pathSet.contains(p.normalize(path)); } - - /// returns if a [Directory] is present on the path of [_projectPath] Future projectExist() { - return fileSystem.isDirectory(_projectPath) - .then((isDirectory) { + return fileSystem.isDirectory(_projectPath).then((isDirectory) { _projectChecked = true; - if(isDirectory){ + if (isDirectory) { _projectDir = fileSystem.directory(_projectPath); - } - else{ + } else { _logger.info( - 'The $_projectPath does not exist or its not of type Directory.'); + 'The $_projectPath does not exist or its not of type Directory.'); } return isDirectory; }); - return fileSystem.type(_projectPath, followLinks: false) - .then((FileSystemEntityType type) { - _projectChecked = true; - if (fileSystem.isDirectorySync(path)) { - _projectDir = fileSystem.directory(_projectPath); - return true; - } - - return false; - }); } /// From the [_projectPath] provided, we are going to scan all the files within and diff --git a/test/lib/generation/file_system_analyzer_test.dart b/test/lib/generation/file_system_analyzer_test.dart new file mode 100644 index 00000000..0c9a3bc8 --- /dev/null +++ b/test/lib/generation/file_system_analyzer_test.dart @@ -0,0 +1,66 @@ +import 'dart:async'; + +import 'package:file/file.dart'; +import 'package:file/memory.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; +import 'package:test/test.dart'; +import 'package:path/path.dart' as p; + +void main() { + group('$FileSystemAnalyzer functions on the current FileSystem', () { + /// Stream used to expose the [FileSystem.opHandle] constructor method + /// to al the test that might want to use it. + StreamController fileSystemUpdates; + FileSystemAnalyzer fileSystemAnalyzer; + FileSystem fileSystem; + final projectPath = 'Path/to/project/'; + setUp(() async { + ///contexting + fileSystemUpdates = StreamController.broadcast(); + fileSystem = MemoryFileSystem.test( + opHandle: (context, operation) => fileSystemUpdates.add(operation)); + await fileSystem.currentDirectory + .childDirectory(projectPath) + .create(recursive: true); + + fileSystemAnalyzer = + FileSystemAnalyzer(projectPath, fileSystem: fileSystem); + }); + + test( + '$FileSystemAnalyzer checking for the existince of a project directory', + () async { + /// create some files within the [projectPath] that we can test the indexing of its files. + var isProjectAvailable = await fileSystemAnalyzer.projectExist(); + expect(isProjectAvailable, true); + }); + + test( + '$FileSystemAnalyzer indexing files within the project path that is passed to it.', + () async { + var cDir = fileSystem.currentDirectory; + var files = [ + './example_directory/some_file.dart', + './parabeac_file.g.dart', + './inside/multiple/directories/inside.dart' + ].map((file) => p.join(projectPath, p.normalize(file))); + + /// Setting up the files within the [fileSystem.currentDirectory] + files.forEach((file) { + cDir.childFile(file).createSync(recursive: true); + }); + + await fileSystemAnalyzer.indexProjectFiles(); + + expect(files.length, fileSystemAnalyzer.paths.length, + reason: + '$FileSystemAnalyzer should contains the same number of paths that the files created.'); + fileSystemAnalyzer.paths.forEach((indexedFile) { + var pathFound = files.contains(indexedFile); + expect(pathFound, true, + reason: + '$FileSystemAnalyzer should index all of the files within directory'); + }); + }); + }); +} From 611cac33c8c2a55dfe4a61c0b6a81e452a8001e2 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 1 Aug 2021 16:57:30 -0600 Subject: [PATCH 269/404] WIP added flag that only creates/replaces the flutter project if it does not exist --- lib/controllers/controller.dart | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index 2aa2023f..0eb2fe1d 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/controllers/interpret.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/input/helper/asset_processing_service.dart'; @@ -55,10 +56,11 @@ abstract class Controller { if (processInfo.exportPBDL) { return stopAndToJson(designProject, apService); } - - var projectGenFuture = await FlutterProjectBuilder.createFlutterProject( - processInfo.projectName, - projectDir: processInfo.outputPath); + var fileSystemAnalyzer = FileSystemAnalyzer(processInfo.genProjectPath); + if (!(await fileSystemAnalyzer.projectExist())) { + await FlutterProjectBuilder.createFlutterProject(processInfo.projectName, + projectDir: processInfo.outputPath); + } Interpret().init(processInfo.genProjectPath, configuration); @@ -70,7 +72,7 @@ abstract class Controller { project: pbProject, pageWriter: PBFlutterWriter()); - await fpb.genProjectFiles(projectGenFuture.item1); + await fpb.genProjectFiles(processInfo.genProjectPath); } void convertFile( From 29983fc469477391de8e5bcf32cc5596d1e024d5 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 1 Aug 2021 17:03:00 -0600 Subject: [PATCH 270/404] WIP the fileSystemAnalyzer is now indexing all the files within the generated flutter project --- lib/controllers/controller.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index 0eb2fe1d..ca8c5aef 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; @@ -51,6 +53,7 @@ abstract class Controller { [AssetProcessingService apService]) async { var processInfo = MainInfo(); var configuration = processInfo.configuration; + var indexFileFuture = Future.value(); /// IN CASE OF JSON ONLY if (processInfo.exportPBDL) { @@ -60,6 +63,8 @@ abstract class Controller { if (!(await fileSystemAnalyzer.projectExist())) { await FlutterProjectBuilder.createFlutterProject(processInfo.projectName, projectDir: processInfo.outputPath); + } else{ + indexFileFuture = fileSystemAnalyzer.indexProjectFiles(); } Interpret().init(processInfo.genProjectPath, configuration); @@ -72,6 +77,7 @@ abstract class Controller { project: pbProject, pageWriter: PBFlutterWriter()); + await indexFileFuture; await fpb.genProjectFiles(processInfo.genProjectPath); } From 3d23666f1a9b7126444fbde5b70f188b9052bef1 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 1 Aug 2021 20:48:08 -0600 Subject: [PATCH 271/404] WIP(476) added the ability to only index files that match extension provided by the caller or if there is no extension provided, then all files are indexed. --- .../file_system_analyzer.dart | 36 ++++++++++++++++--- .../generation/file_system_analyzer_test.dart | 11 ++++-- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lib/generation/flutter_project_builder/file_system_analyzer.dart b/lib/generation/flutter_project_builder/file_system_analyzer.dart index 66d2c540..80c7e3f9 100644 --- a/lib/generation/flutter_project_builder/file_system_analyzer.dart +++ b/lib/generation/flutter_project_builder/file_system_analyzer.dart @@ -25,6 +25,15 @@ class FileSystemAnalyzer { p.PathSet _pathSet; List get paths => _pathSet.toList(); + /// These are the extensions that should be indexed, if the [Set] is empty then, its + /// going to assume that all the files should be indexed. + /// + /// For example, [_extensions] contains `.dart`, then only the `dart` files are going + /// to be indexed. In other words, we are only going to care if `dart` files have been changed or + /// missing. + Iterable get extensions => _extensions.toList(); + Set _extensions; + /// Path of where the project [Directory] is located. String _projectPath; String get projectPath => _projectPath; @@ -36,11 +45,13 @@ class FileSystemAnalyzer { /// times. bool _projectChecked = false; - FileSystemAnalyzer(String projectPath, {this.fileSystem}) { + FileSystemAnalyzer(String projectPath, + {this.fileSystem}) { assert(projectPath != null); _logger = Logger(runtimeType.toString()); fileSystem ??= LocalFileSystem(); + _extensions = {}; _projectPath = p.normalize(projectPath); _pathSet = p.PathSet(context: p.Context()); @@ -53,6 +64,17 @@ class FileSystemAnalyzer { return _pathSet.contains(p.normalize(path)); } + /// Adding [ext] to the files that should be taken into consideration when + /// running [indexProjectFiles]. + /// + /// [level] represents 'how many dots from the end, for example, [level] of + /// `1` could return `.dart` from `.g.dart`, [level] `2` would return `.g.dart` + void addFileExtension(String ext, [int level = 1]) { + if (ext != null) { + _extensions.add(p.extension(ext, level)); + } + } + /// returns if a [Directory] is present on the path of [_projectPath] Future projectExist() { return fileSystem.isDirectory(_projectPath).then((isDirectory) { @@ -67,8 +89,11 @@ class FileSystemAnalyzer { }); } - /// From the [_projectPath] provided, we are going to scan all the files within and - /// save them in [_pathSet] + /// From the [_projectPath] provided, we are going to scan all the [File]s within and + /// save them in [_pathSet]. + /// + /// All the [File]s are going to be indexed if [_extensions.isEmpty], if not, only the [File]s + /// that contain any extension of [extension] within [File.path]. Future indexProjectFiles() async { if (!_projectChecked) { await projectExist(); @@ -81,7 +106,10 @@ class FileSystemAnalyzer { _logger.info('Indexing files within $projectPath...'); var filePaths = await _projectDir .list(recursive: true, followLinks: false) - .where((entity) => entity is File) + .where((entity) => + entity is File && + (_extensions.isEmpty || + _extensions.any((ext) => entity.path.contains(ext)))) .cast() .map((File file) => p.normalize(file.path)) .toList(); diff --git a/test/lib/generation/file_system_analyzer_test.dart b/test/lib/generation/file_system_analyzer_test.dart index 0c9a3bc8..245f6ced 100644 --- a/test/lib/generation/file_system_analyzer_test.dart +++ b/test/lib/generation/file_system_analyzer_test.dart @@ -42,7 +42,8 @@ void main() { var files = [ './example_directory/some_file.dart', './parabeac_file.g.dart', - './inside/multiple/directories/inside.dart' + './inside/multiple/directories/inside.dart', + './testing_extension/should_be_ignored.txt' ].map((file) => p.join(projectPath, p.normalize(file))); /// Setting up the files within the [fileSystem.currentDirectory] @@ -50,11 +51,15 @@ void main() { cDir.childFile(file).createSync(recursive: true); }); + /// [fileSystemAnalyzer] should strip anything that is not the actual file extension + fileSystemAnalyzer.addFileExtension('extension.dart'); + expect(fileSystemAnalyzer.extensions.contains('.dart'), true); + await fileSystemAnalyzer.indexProjectFiles(); - expect(files.length, fileSystemAnalyzer.paths.length, + expect((files.length - 1), fileSystemAnalyzer.paths.length, reason: - '$FileSystemAnalyzer should contains the same number of paths that the files created.'); + '$FileSystemAnalyzer should contain one less than the number of files because of the extension filter we set (.dart files).'); fileSystemAnalyzer.paths.forEach((indexedFile) { var pathFound = files.contains(indexedFile); expect(pathFound, true, From 87fe1d0a6302f29aa78564b1dda0c768abd61c5c Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 1 Aug 2021 21:14:50 -0600 Subject: [PATCH 272/404] WIP(476) FIX some extension inconsistencies, where if a raw extension is passed, the path package would return empty string. --- lib/controllers/controller.dart | 2 ++ .../file_system_analyzer.dart | 10 +++++---- .../generation/file_system_analyzer_test.dart | 21 +++++++++++++++---- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index ca8c5aef..1cd24100 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -60,6 +60,8 @@ abstract class Controller { return stopAndToJson(designProject, apService); } var fileSystemAnalyzer = FileSystemAnalyzer(processInfo.genProjectPath); + fileSystemAnalyzer.addFileExtension('.dart'); + if (!(await fileSystemAnalyzer.projectExist())) { await FlutterProjectBuilder.createFlutterProject(processInfo.projectName, projectDir: processInfo.outputPath); diff --git a/lib/generation/flutter_project_builder/file_system_analyzer.dart b/lib/generation/flutter_project_builder/file_system_analyzer.dart index 80c7e3f9..54f6c23c 100644 --- a/lib/generation/flutter_project_builder/file_system_analyzer.dart +++ b/lib/generation/flutter_project_builder/file_system_analyzer.dart @@ -45,8 +45,7 @@ class FileSystemAnalyzer { /// times. bool _projectChecked = false; - FileSystemAnalyzer(String projectPath, - {this.fileSystem}) { + FileSystemAnalyzer(String projectPath, {this.fileSystem}) { assert(projectPath != null); _logger = Logger(runtimeType.toString()); @@ -66,12 +65,15 @@ class FileSystemAnalyzer { /// Adding [ext] to the files that should be taken into consideration when /// running [indexProjectFiles]. - /// + /// /// [level] represents 'how many dots from the end, for example, [level] of /// `1` could return `.dart` from `.g.dart`, [level] `2` would return `.g.dart` void addFileExtension(String ext, [int level = 1]) { if (ext != null) { - _extensions.add(p.extension(ext, level)); + /// [ext] could just be `.dart` in which case [p.extension] would return and empty string, + /// therefore, we have to check if its just the raw extension or not. + ext = ext.startsWith('.') ? ext : p.extension(ext, level); + _extensions.add(ext); } } diff --git a/test/lib/generation/file_system_analyzer_test.dart b/test/lib/generation/file_system_analyzer_test.dart index 245f6ced..f3b114bc 100644 --- a/test/lib/generation/file_system_analyzer_test.dart +++ b/test/lib/generation/file_system_analyzer_test.dart @@ -39,11 +39,15 @@ void main() { '$FileSystemAnalyzer indexing files within the project path that is passed to it.', () async { var cDir = fileSystem.currentDirectory; + var testingExtension = '.dart'; + var testingExtension2 = '.js'; var files = [ './example_directory/some_file.dart', './parabeac_file.g.dart', './inside/multiple/directories/inside.dart', - './testing_extension/should_be_ignored.txt' + './testing_extension/should_be_ignored.txt', + './another_extension/test/.gitignore', + './testing_raw_extension_input/index.js' ].map((file) => p.join(projectPath, p.normalize(file))); /// Setting up the files within the [fileSystem.currentDirectory] @@ -52,12 +56,21 @@ void main() { }); /// [fileSystemAnalyzer] should strip anything that is not the actual file extension - fileSystemAnalyzer.addFileExtension('extension.dart'); - expect(fileSystemAnalyzer.extensions.contains('.dart'), true); + fileSystemAnalyzer.addFileExtension('extension$testingExtension'); + expect(fileSystemAnalyzer.extensions.contains(testingExtension), true); + + // [fileSystemAnalyzer] should also accept raw extension + fileSystemAnalyzer.addFileExtension(testingExtension2); + expect(fileSystemAnalyzer.extensions.contains(testingExtension2), true); await fileSystemAnalyzer.indexProjectFiles(); - expect((files.length - 1), fileSystemAnalyzer.paths.length, + expect( + files.where((path) { + var ext = p.extension(path); + return ext == testingExtension || ext == testingExtension2; + }).length, + fileSystemAnalyzer.paths.length, reason: '$FileSystemAnalyzer should contain one less than the number of files because of the extension filter we set (.dart files).'); fileSystemAnalyzer.paths.forEach((indexedFile) { From d3253b6fa126b2a1f751d614cf527577bce55fbe Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 3 Aug 2021 15:10:38 -0600 Subject: [PATCH 273/404] WIP(476) CREATED FileOwnershipPolicy class for easy assignment of extension based on ownership --- .../commands/file_structure_command.dart | 7 ++- .../file_ownership_policy.dart | 48 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 lib/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart index 7800c06b..62c08b7c 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart @@ -1,5 +1,10 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; - +import 'package:path/path.dart' as p; +/// [FileStructureCommand] uses the command pattern to create units of works that create/modify the +/// FileSystem. +/// +/// The [FileStructureCommand]s are send to the [FileStructureCommand] that is responsible for +/// executing the command and actually writing them into the file system. abstract class FileStructureCommand { final String UUID; diff --git a/lib/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart b/lib/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart new file mode 100644 index 00000000..e0b6cd89 --- /dev/null +++ b/lib/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart @@ -0,0 +1,48 @@ +import 'package:file/file.dart'; + +/// Policy that tells the caller what [File] extension to use depending of +/// the [File]'s [FileOwnership]. +/// +/// For example, if the [File] is own by the developer, then we are going +/// to use the extension for [FileOwnership.DEV]; vice versa with [FileOwnership.PBC]. This +/// is primarly used when creating the [File]s, depicting if a [File] is going to +/// be manipulated by the developer or the Parabeac-Core system. It prevents the +/// accidental deletion of any of the users writing code in the central location. +abstract class FileOwnershipPolicy { + /// The extension the developer own [File]s are going to have. + FileOwnership fileOwnership; + + /// Based on the [ownership], its going to return the proper [File] extension. + String getFileExtension(FileOwnership ownership); +} + +/// The possible [FileOwnership] that could exist at once. +enum FileOwnership { DEV, PBC } + +/// Exception regarding the [FileOwnershipPolicy] +class FileOwnershipPolicyError extends IOException { + final String message; + + FileOwnershipPolicyError(this.message); + + @override + String toString() => message; +} + +/// This [FileOwnershipPolicy] enforces the developer own files to have the `.dart` extension, +/// while the Parabeac-Core own files with the `.g.dart` extension. +class DotGFileOwnershipPolicy implements FileOwnershipPolicy { + @override + FileOwnership fileOwnership; + + @override + String getFileExtension(FileOwnership ownership) { + switch (ownership) { + case FileOwnership.DEV: + return '.dart'; + case FileOwnership.PBC: + default: + return '.g.dart'; + } + } +} From 860391f1ca4407c8633f5e982f2e4879015c4bc7 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 3 Aug 2021 18:14:10 -0600 Subject: [PATCH 274/404] (476)ENABLED file ownershop, which in returns, enables file extensions based on the file owner. --- .../state_management/bloc_middleware.dart | 2 +- .../commands/entry_file_command.dart | 9 ++++++--- .../commands/export_platform_command.dart | 6 ++++-- .../commands/node_file_structure_command.dart | 10 +++++++++- .../commands/write_screen_command.dart | 9 ++++++--- .../commands/write_symbol_command.dart | 9 ++++++--- .../pb_file_structure_strategy.dart | 18 ++++++++++++------ 7 files changed, 44 insertions(+), 19 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index c0b01cb1..69e6b3c3 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -138,7 +138,7 @@ class BLoCMiddleware extends StateManagementMiddleware { 'STATE${node.currentContext.tree.UUID}', '${generalName}_state', stateBuffer.toString(), - symbolPath: blocDirectory)); + symbolPath: blocDirectory,)); /// Creates map page mapBuffer.write(_makeStateToWidgetFunction(node)); diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart index 4cded48a..546f87a7 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/entry_file_command.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:path/path.dart' as p; @@ -29,7 +30,8 @@ class EntryFileCommand extends NodeFileStructureCommand { this.entryScreenName, this.entryScreenImport, this.projectName = 'Parabeac-Core Generated Project', - this.mainCode = 'runApp(MyApp());'}) + this.mainCode = 'runApp(MyApp());', + FileOwnership ownership = FileOwnership.DEV}) : super('ENTRY_FILE', ''' import 'package:flutter/material.dart'; $entryScreenImport @@ -53,7 +55,7 @@ class MyApp extends StatelessWidget { } } - ''') { + ''', ownership) { if ((entryScreenImport == null && entryScreenName != null) || (entryScreenName == null && entryScreenName != null)) { throw NullThrownError(); @@ -64,6 +66,7 @@ class MyApp extends StatelessWidget { Future write(FileStructureStrategy strategy) { strategy.writeDataToFile( code, strategy.GENERATED_PROJECT_PATH, p.join('lib', mainFileName), - UUID: UUID); + UUID: UUID, + ownership: ownership); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart index 740a6010..2da9f045 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/export_platform_command.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -16,7 +17,8 @@ class ExportPlatformCommand extends NodeFileStructureCommand { this.folderName, this.fileName, String code, - ) : super(UUID, code); + {FileOwnership ownership = FileOwnership.PBC} + ) : super(UUID, code, ownership); @override Future write(FileStructureStrategy strategy) async { @@ -26,6 +28,6 @@ class ExportPlatformCommand extends NodeFileStructureCommand { folderName, platform.toString().toLowerCase().replaceAll('platform.', ''), ); - strategy.writeDataToFile(code, path, fileName, UUID: UUID); + strategy.writeDataToFile(code, path, fileName, UUID: UUID, ownership: ownership); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart index 10e6a87b..4766a983 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart @@ -1,7 +1,15 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; /// Class that relies on `code` to implement its `write` method. abstract class NodeFileStructureCommand extends FileStructureCommand { String code; - NodeFileStructureCommand(String UUID, this.code) : super(UUID); + + /// Depicts the [FileOwnership] of the files that is going to be created + /// through [write] + FileOwnership ownership; + + NodeFileStructureCommand(String UUID, this.code, + this.ownership) + : super(UUID); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 221c2656..697b270e 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -9,8 +10,9 @@ class WriteScreenCommand extends NodeFileStructureCommand { static final SCREEN_PATH = 'lib/screens'; - WriteScreenCommand(String UUID, this.name, this.relativePath, String code) - : super(UUID, code); + WriteScreenCommand(String UUID, this.name, this.relativePath, String code, + {FileOwnership ownership = FileOwnership.PBC}) + : super(UUID, code, ownership); /// Writes a screen file containing [code] to [path] with [name] as its filename. /// @@ -19,7 +21,8 @@ class WriteScreenCommand extends NodeFileStructureCommand { Future write(FileStructureStrategy strategy) { var absPath = p.join(strategy.GENERATED_PROJECT_PATH, SCREEN_PATH, relativePath); - strategy.writeDataToFile(code, absPath, name, UUID: UUID); + strategy.writeDataToFile(code, absPath, name, + UUID: UUID, ownership: ownership); return Future.value(p.join(absPath, name)); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 860e5918..7606b4f5 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/node_file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -16,8 +17,10 @@ class WriteSymbolCommand extends NodeFileStructureCommand { String relativePath; WriteSymbolCommand(String UUID, this.fileName, String code, - {this.relativePath = '', this.symbolPath = DEFAULT_SYMBOL_PATH}) - : super(UUID, code); + {this.relativePath = '', + this.symbolPath = DEFAULT_SYMBOL_PATH, + FileOwnership ownership = FileOwnership.PBC}) + : super(UUID, code, ownership); /// Writes a symbol file containing [data] with [fileName] as its filename. /// @@ -28,7 +31,7 @@ class WriteSymbolCommand extends NodeFileStructureCommand { ? p.join(strategy.GENERATED_PROJECT_PATH, symbolPath) : p.join(strategy.GENERATED_PROJECT_PATH, symbolPath, relativePath); - strategy.writeDataToFile(code, absPath, fileName, UUID: UUID); + strategy.writeDataToFile(code, absPath, fileName, UUID: UUID, ownership: ownership); return Future.value(p.join(absPath, fileName)); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 0f0bd442..be1bb7d0 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/flutter_project_builder/file_writer_observer.dart'; @@ -65,14 +66,18 @@ abstract class FileStructureStrategy implements CommandInvoker { /// Notifies the [fileObserver] of when a file supposed to be created. bool notifyObserverInDryRun = true; + /// How the extension of the [File]s are going to be written based on the ownership of + /// the [File]. + FileOwnershipPolicy fileOwnershipPolicy; + String _screenDirectoryPath; String _viewDirectoryPath; FileStructureStrategy( - this.GENERATED_PROJECT_PATH, - this._pageWriter, - this._pbProject, - ); + this.GENERATED_PROJECT_PATH, this._pageWriter, this._pbProject, + {this.fileOwnershipPolicy}) { + fileOwnershipPolicy ??= DotGFileOwnershipPolicy(); + } void addFileObserver(FileWriterObserver observer) { if (observer != null) { @@ -158,8 +163,9 @@ abstract class FileStructureStrategy implements CommandInvoker { /// /// [FileWriterObserver]s are going to be notfied of the new created file. void writeDataToFile(String data, String directory, String name, - {String UUID, String ext = '.dart'}) { - var file = getFile(directory, p.setExtension(name, ext)); + {String UUID, FileOwnership ownership}) { + var file = getFile(directory, + p.setExtension(name, fileOwnershipPolicy.getFileExtension(ownership))); if (!dryRunMode) { file.createSync(recursive: true); From 67983559a09b4fc1f3c18bfb864ae85ae5902781 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 4 Aug 2021 15:30:47 -0600 Subject: [PATCH 275/404] ADDED more logging to the interpret class, FIX wrong order for positional parameters in injected tabbar, and ABSTRACTED the logging attribute of AITHandlers. --- lib/controllers/interpret.dart | 65 ++++++++++++++----- lib/eggs/injected_tab_bar.dart | 8 +-- .../pb_alignment_generation_service.dart | 9 +-- .../pb_constraint_generation_service.dart | 2 +- .../services/pb_generation_service.dart | 6 +- .../pb_layout_generation_service.dart | 5 +- .../services/pb_plugin_control_service.dart | 18 +++-- .../services/pb_symbol_linker_service.dart | 2 +- 8 files changed, 71 insertions(+), 44 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 755a8019..7483db2e 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -20,6 +20,7 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_ import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_visual_generation_service.dart'; import 'package:quick_log/quick_log.dart'; +import 'package:tuple/tuple.dart'; class Interpret { var log = Logger('Interpret'); @@ -123,8 +124,9 @@ class AITServiceBuilder { Stopwatch _stopwatch; /// These are the [AITHandler]s that are going to be transforming - /// the [_intermediateTree]. - final List _transformations = []; + /// the [_intermediateTree] in a [Tuple2]. The [Tuple2.item1] is the id, if any, and + /// [Tuple2.item2] is the actual [AITHandler] + final List _transformations = []; final DesignNode designNode; @@ -140,22 +142,26 @@ class AITServiceBuilder { } } - AITServiceBuilder addTransformation(transformation) { + /// Adding a [transformation] that will be applyed to the [PBIntermediateTree]. The [id] + /// is to [log] the [transformation]. + AITServiceBuilder addTransformation(transformation, {String id}) { + id ??= transformation.runtimeType.toString(); if (transformation is AITHandler) { - _transformations.add(transformation.handleTree); - } else if (transformation is AITNodeTransformation || transformation is PBDLConversion) { - _transformations.add(transformation); - } + _transformations.add(Tuple2(id, transformation.handleTree)); + } else if (transformation is AITNodeTransformation || + transformation is PBDLConversion) { + _transformations.add(Tuple2(id, transformation)); + } return this; } /// Verifies that only the allows data types are within the [_transformations] bool _verifyTransformationsFailed() { return _transformations.any((transformation) => - transformation is! AITHandler && - transformation is! AITNodeTransformation && - transformation is! PBDLConversion && - transformation is! AITTransformation); + transformation.item2 is! AITHandler && + transformation.item2 is! AITNodeTransformation && + transformation.item2 is! PBDLConversion && + transformation.item2 is! AITTransformation); } Future _pbdlConversion(PBDLConversion conversion) async { @@ -163,6 +169,9 @@ class AITServiceBuilder { _stopwatch.start(); log.fine('Converting ${designNode.name} to AIT'); _intermediateTree = await conversion(designNode, _context); + + assert(_intermediateTree != null, + 'All PBDL conversions should yield a IntermediateTree'); _context.tree = _intermediateTree; _stopwatch.stop(); log.fine( @@ -173,22 +182,34 @@ class AITServiceBuilder { log.error('PBDL Conversion was not possible because of - \n$e'); exit(1); - } + } } Future build() async { var pbdlConversion = _transformations - .firstWhere((transformation) => transformation is PBDLConversion); + .firstWhere((transformation) => transformation.item2 is PBDLConversion) + .item2; if (pbdlConversion == null) { throw Error(); } - _transformations.removeWhere((element) => element is PBDLConversion); + _transformations.removeWhere((element) => element.item2 is PBDLConversion); await _pbdlConversion(pbdlConversion); - for (var transformation in _transformations) { - var name = transformation.toString(); + if (_intermediateTree == null || _intermediateTree.rootNode == null) { + log.warning( + 'Skipping ${designNode.name} as either $PBIntermediateTree or $PBIntermediateTree.rootNode is null'); + return Future.value(_intermediateTree); + } + + var treeName = _intermediateTree.name; + log.fine('Transforming $treeName ...'); + + for (var transformationTuple in _transformations) { + var transformation = transformationTuple.item2; + var name = transformationTuple.item1; + _stopwatch.start(); - log.fine('Started running $name...'); + log.debug('Started running $name...'); try { if (transformation is AITNodeTransformation) { for (var node in _intermediateTree) { @@ -197,14 +218,22 @@ class AITServiceBuilder { } else if (transformation is AITTransformation) { _intermediateTree = await transformation(_context, _intermediateTree); } + + if (_intermediateTree == null || _intermediateTree.rootNode == null) { + log.error( + 'The $name returned a null \"$treeName\" $PBIntermediateTree (or its rootnode is null)\n after its transformation, this will remove the tree from the process!'); + throw NullThrownError(); + } } catch (e) { MainInfo().captureException(e); log.error('${e.toString()} at $name'); } finally { _stopwatch.stop(); - log.fine('stoped running $name (${_stopwatch.elapsed.inMilliseconds})'); + log.debug( + 'Stoped running $name (${_stopwatch.elapsed.inMilliseconds})'); } } + log.fine('Finish transforming $treeName'); return _intermediateTree; } } diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 93e3a758..84a71956 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -13,7 +13,6 @@ import 'dart:math'; import 'injected_tab.dart'; class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { - @override String semanticName = ''; @@ -41,7 +40,9 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { .name .contains('')) { assert(node is! Tab, 'node should be a Tab'); - getAttributeNamed('tabs').attributeNodes.add(node as PBIntermediateNode); + getAttributeNamed('tabs') + .attributeNodes + .add(node as PBIntermediateNode); } } @@ -53,12 +54,11 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override List layoutInstruction(List layer) {} - @override PBEgg generatePluginNode( Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef) { return InjectedTabBar( - topLeftCorner, bottomRightCorner, UUID, originalRef.name, + topLeftCorner, bottomRightCorner, originalRef.name, UUID, currentContext: currentContext); } diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index bc40fab1..b94533a0 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -9,20 +9,17 @@ import 'package:quick_log/quick_log.dart'; /// Interpret the alignment relationship between a child node and a parent Visual or Layout Node. After interpretation, inject the proper alignment whether that’s Padding based or Flex-based. /// Input: PBIntermediateNode Tree /// Output: PBIntermediateNode Tree -class PBAlignGenerationService implements AITHandler { - var log; +class PBAlignGenerationService extends AITHandler { /// Constructor for PBPluginGenerationService, must include the root SketchNode - PBAlignGenerationService() { - log = Logger(runtimeType.toString()); - } + PBAlignGenerationService(); /// Should find all layout nodes Future addAlignmentToLayouts( PBIntermediateTree tree, PBContext context) { var originalRoot = tree.rootNode; if (originalRoot == null) { - log.warning( + logger.warning( '[PBAlignmentGenerationService] generate() attempted to generate a non-existing tree'); return null; } diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index c3c607bf..ba28e4a3 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; ///tree.where((element) => element != null).toList().reversed.map((e) => e.name).toList() -class PBConstraintGenerationService implements AITHandler { +class PBConstraintGenerationService extends AITHandler { PBConstraintGenerationService(); /// Traverse to the bottom of the tree, and implement constraints to nodes that don't already contain it such as [InjectedContainer] and then work our way up the tree. diff --git a/lib/interpret_and_optimize/services/pb_generation_service.dart b/lib/interpret_and_optimize/services/pb_generation_service.dart index 3d9d7d9a..6fe13185 100644 --- a/lib/interpret_and_optimize/services/pb_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_generation_service.dart @@ -2,14 +2,18 @@ import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:quick_log/quick_log.dart'; /// Abstract class for Generatiion Services /// so they all have the current context abstract class AITHandler { + Logger logger; /// Delegates the tranformation/modification to the current [AITHandler] Future handleTree( PBContext context, PBIntermediateTree tree); - AITHandler(); + AITHandler(){ + logger = Logger(runtimeType.toString()); + } } typedef AITTransformation = Future Function( diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 9e148e15..ce803674 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -20,11 +20,10 @@ import 'package:tuple/tuple.dart'; /// Inject PBLayoutIntermediateNode to a PBIntermediateNode Tree that signifies the grouping of PBItermediateNodes in a given direction. There should not be any PBAlignmentIntermediateNode in the input tree. /// Input: PBVisualIntermediateNode Tree or PBLayoutIntermediate Tree /// Output:PBIntermediateNode Tree -class PBLayoutGenerationService implements AITHandler { +class PBLayoutGenerationService extends AITHandler { ///The available Layouts that could be injected. final List _availableLayouts = []; - var log = Logger('Layout Generation Service'); ///[LayoutRule] that check post conditions. final List _postLayoutRules = [ @@ -96,7 +95,7 @@ class PBLayoutGenerationService implements AITHandler { exception: e, stackTrace: stackTrace, ); - log.error(e.toString()); + logger.error(e.toString()); } finally { tree.rootNode = rootNode; return Future.value(tree); diff --git a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart index 9aa810d4..9f15aff0 100644 --- a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart +++ b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart @@ -12,21 +12,18 @@ import 'package:quick_log/quick_log.dart'; /// When finding a plugin node, we call layoutInstruction(). This gives the PluginNdoe the ability to modify the relevant tree if needed. /// Input: PBIntermediateTree /// Output: PBIntermediateTree -class PBPluginControlService implements AITHandler { - - - var log = Logger('Plugin Control Service'); - +class PBPluginControlService extends AITHandler { /// Constructor for PBPluginGenerationService, must include the root SketchNode PBPluginControlService(); /// Builds and returns intermediate tree by breadth depth first. /// @return Returns the root node of the intermediate tree. - Future convertAndModifyPluginNodeTree(PBIntermediateTree tree, PBContext context) { + Future convertAndModifyPluginNodeTree( + PBIntermediateTree tree, PBContext context) { var originalRoot = tree.rootNode; if (originalRoot == null) { - log.warning( - '[PBPluginControlService] generate() attempted to generate a non-existing tree.'); + logger.warning( + 'generate() attempted to generate a non-existing tree.'); return null; } @@ -42,7 +39,7 @@ class PBPluginControlService implements AITHandler { currentIntermediateNode.layoutInstruction(currentLayer.nodeLayer); if (layerToReplace == null && currentLayer.nodeLayer != null) { // print('Deleting an entire layer, was this on purpose?'); - log.warning('Deleting an entire layer, was this on purpose?'); + logger.warning('Deleting an entire layer, was this on purpose?'); currentLayer.nodeLayer = layerToReplace; break; @@ -85,7 +82,8 @@ class PBPluginControlService implements AITHandler { } @override - Future handleTree(PBContext context, PBIntermediateTree tree) { + Future handleTree( + PBContext context, PBIntermediateTree tree) { return convertAndModifyPluginNodeTree(tree, context); } } diff --git a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart index 3b30916d..4300afa8 100644 --- a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart @@ -9,7 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.d import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_shared_aggregation_service.dart'; -class PBSymbolLinkerService implements AITHandler{ +class PBSymbolLinkerService extends AITHandler{ PBSymbolStorage _symbolStorage; PBSharedInterAggregationService _aggregationService; From af005a2090e256146fccb75c5146d6c2b8514630 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 4 Aug 2021 18:15:07 -0600 Subject: [PATCH 276/404] REFACTORED the FileOwnershipPolicy from proposing their own file extension to modifying an existing file extension. --- .../file_ownership_policy.dart | 34 ++++++++++++++----- .../pb_file_structure_strategy.dart | 20 ++++++++--- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart b/lib/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart index e0b6cd89..f87b7bef 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart @@ -12,8 +12,11 @@ abstract class FileOwnershipPolicy { /// The extension the developer own [File]s are going to have. FileOwnership fileOwnership; - /// Based on the [ownership], its going to return the proper [File] extension. - String getFileExtension(FileOwnership ownership); + /// Based on the [ownership], its going to return the proper [File] extension. This is + /// done by modifying the [existingExtension] because its better to assume that the [File] + /// extension is not going to be the same forever. Might be only `.dart` right now, but it + /// could easily support `.json` tomorrow. + String getFileExtension(FileOwnership ownership, String existingExtension); } /// The possible [FileOwnership] that could exist at once. @@ -29,6 +32,16 @@ class FileOwnershipPolicyError extends IOException { String toString() => message; } +/// This [IOException] is thrown when the wrong [File] extension(or something unexpected) +/// is given to the [FileOwnershipPolicy.getFileExtension]. +class FileWrongExtensionFormat extends IOException { + final String message; + + FileWrongExtensionFormat(this.message); + @override + String toString() => message; +} + /// This [FileOwnershipPolicy] enforces the developer own files to have the `.dart` extension, /// while the Parabeac-Core own files with the `.g.dart` extension. class DotGFileOwnershipPolicy implements FileOwnershipPolicy { @@ -36,13 +49,16 @@ class DotGFileOwnershipPolicy implements FileOwnershipPolicy { FileOwnership fileOwnership; @override - String getFileExtension(FileOwnership ownership) { - switch (ownership) { - case FileOwnership.DEV: - return '.dart'; - case FileOwnership.PBC: - default: - return '.g.dart'; + String getFileExtension(FileOwnership ownership, String existingExtension) { + if (!existingExtension.startsWith('.')) { + throw FileWrongExtensionFormat( + 'Wrong extension of $existingExtension given to $runtimeType, it only supports extensions starting with \'.\''); } + if (ownership == FileOwnership.DEV) { + return existingExtension; + } + + var modExt = '.g' + existingExtension; + return modExt; } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index be1bb7d0..c578da22 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -162,10 +162,13 @@ abstract class FileStructureStrategy implements CommandInvoker { /// be used. /// /// [FileWriterObserver]s are going to be notfied of the new created file. + /// TODO: aggregate parameters into a file class void writeDataToFile(String data, String directory, String name, - {String UUID, FileOwnership ownership}) { - var file = getFile(directory, - p.setExtension(name, fileOwnershipPolicy.getFileExtension(ownership))); + {String UUID, FileOwnership ownership, String ext = '.dart'}) { + var file = getFile( + directory, + p.setExtension( + name, fileOwnershipPolicy.getFileExtension(ownership, ext))); if (!dryRunMode) { file.createSync(recursive: true); @@ -187,9 +190,16 @@ abstract class FileStructureStrategy implements CommandInvoker { /// no file is found, then its going to run [writeDataToFile]. [appendIfFound] flag /// appends the information only if that information does not exist in the file. If no /// [ModFile] function is found, its going to append the information at the end of the lines + /// TODO: aggregate the parameters into a file class void appendDataToFile(ModFile modFile, String directory, String name, - {String UUID, bool createFileIfNotFound = true, String ext = '.dart'}) { - name = p.setExtension(name, ext); + {String UUID, + bool createFileIfNotFound = true, + String ext = '.dart', + FileOwnership ownership}) { + name = ownership == null + ? p.setExtension(name, ext) + : p.setExtension( + name, fileOwnershipPolicy.getFileExtension(ownership, ext)); var file = getFile(directory, name); if (file.existsSync()) { var fileLines = file.readAsLinesSync(); From fe57e1b4d77e97b91e951c7d22b603f49849d946 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 4 Aug 2021 18:43:25 -0600 Subject: [PATCH 277/404] ADDED test for FileOwnershipPolicy and making sure (476) output the correct files. --- test/lib/generation/file_system_test.dart | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 test/lib/generation/file_system_test.dart diff --git a/test/lib/generation/file_system_test.dart b/test/lib/generation/file_system_test.dart new file mode 100644 index 00000000..f1a0eecc --- /dev/null +++ b/test/lib/generation/file_system_test.dart @@ -0,0 +1,34 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; +import 'package:test/test.dart'; + +void main() { + group( + '$FileOwnershipPolicy returning the proper extension given an existing file extension', + () { + String existingFileExtension; + FileOwnershipPolicy ownershipPolicy; + setUp(() { + ownershipPolicy = DotGFileOwnershipPolicy(); + }); + + test('Testing the .g extension modification', () { + existingFileExtension = '.dart'; + var extDevFile = existingFileExtension; + var pbcDevFile = '.g$existingFileExtension'; + + var reasonMessage = (actualExt, ownership, correctExt) => + 'Not returning the correct file extension ($correctExt) when its $ownership own by passing $actualExt'; + + var actualDevExt = ownershipPolicy.getFileExtension( + FileOwnership.DEV, existingFileExtension); + expect(actualDevExt, extDevFile, + reason: reasonMessage(actualDevExt, FileOwnership.DEV, extDevFile)); + + var actualPBCExt = ownershipPolicy.getFileExtension( + FileOwnership.PBC, existingFileExtension); + expect(actualPBCExt, pbcDevFile, + reason: reasonMessage( + actualPBCExt, FileOwnership.PBC, existingFileExtension)); + }); + }); +} From 741985f6e342e1f85eef34df07cdf282f910f5ee Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 4 Aug 2021 18:49:53 -0600 Subject: [PATCH 278/404] FIX wrong imports in some of the test files. --- .../value_objects/file_resource.dart | 64 +++++++++++++++++++ test/lib/generation/generator_test.dart | 3 +- .../padding_dynamic_size_test.dart | 3 +- .../services/interpret_test.dart | 2 +- .../services/prototype_linker_test.dart | 3 +- .../services/symbol_link_test.dart | 3 +- test/lib/layouts/layout_generation_test.dart | 3 +- test/lib/layouts/layout_post_rules_test.dart | 3 +- 8 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 lib/generation/generators/value_objects/file_resource.dart diff --git a/lib/generation/generators/value_objects/file_resource.dart b/lib/generation/generators/value_objects/file_resource.dart new file mode 100644 index 00000000..23fc6dee --- /dev/null +++ b/lib/generation/generators/value_objects/file_resource.dart @@ -0,0 +1,64 @@ +import 'dart:io'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:path/path.dart' as p; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; + +/// Represents a wrapper to a [File] that is going to be written in the File System +class FileResource { + /// Unique Identifier to the [FileResource] + String UUID; + + /// The parent directory that the [file] is located at. + String dirName; + + /// The basename of the [file] + String fileName; + + /// The file extension for [file] + String fileExtension; + + /// The path for the [file] + String path; + + FileOwnership ownership; + + FileStructureStrategy fileSystem; + + File get file => _file; + File _file; + + FileResource( + {this.UUID, + this.dirName, + this.fileName, + this.path, + this.fileExtension = '.dart', + this.fileSystem, + File file}) { + assert( + (dirName == null && fileName == null) && path == null || file == null, + 'Either the [dirName] & [fileName] or [path] should be specified and not null'); + if (path != null) { + dirName = p.dirname(path); + fileName = p.basename(path); + + var extInPath = p.extension(path); + if (extInPath != null || extInPath.isNotEmpty) { + fileExtension = extInPath; + } + } else if (file != null) { + fileName = p.basename(file.path); + dirName = p.dirname(file.path); + fileExtension = p.extension(file.path); + } else { + path = p.join(dirName, fileName, fileExtension); + } + } + + void _constructFile() {} + + void resolveFileExtension({FileOwnershipPolicy policy}) { + assert(policy != null && fileSystem != null, + 'No way of resolving the file extension with null $policy and $FileStructureStrategy'); + } +} diff --git a/test/lib/generation/generator_test.dart b/test/lib/generation/generator_test.dart index f66972c0..c544d6dc 100644 --- a/test/lib/generation/generator_test.dart +++ b/test/lib/generation/generator_test.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; @@ -9,7 +11,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dar import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:test/test.dart'; import 'package:mockito/mockito.dart'; diff --git a/test/lib/input_services/padding_dynamic_size_test.dart b/test/lib/input_services/padding_dynamic_size_test.dart index c5625f4e..c08eb6d6 100644 --- a/test/lib/input_services/padding_dynamic_size_test.dart +++ b/test/lib/input_services/padding_dynamic_size_test.dart @@ -1,10 +1,11 @@ +import 'dart:math'; + import 'package:mockito/mockito.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:test/test.dart'; import 'package:uuid/uuid.dart'; diff --git a/test/lib/interpret_and_optimize/services/interpret_test.dart b/test/lib/interpret_and_optimize/services/interpret_test.dart index 3ffce263..180c1919 100644 --- a/test/lib/interpret_and_optimize/services/interpret_test.dart +++ b/test/lib/interpret_and_optimize/services/interpret_test.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'dart:math'; import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/controllers/main_info.dart'; @@ -15,7 +16,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:test/test.dart'; import 'package:mockito/mockito.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; diff --git a/test/lib/interpret_and_optimize/services/prototype_linker_test.dart b/test/lib/interpret_and_optimize/services/prototype_linker_test.dart index 709f6994..117d9e5b 100644 --- a/test/lib/interpret_and_optimize/services/prototype_linker_test.dart +++ b/test/lib/interpret_and_optimize/services/prototype_linker_test.dart @@ -1,9 +1,10 @@ +import 'dart:math'; + import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:test/test.dart'; import 'package:mockito/mockito.dart'; diff --git a/test/lib/interpret_and_optimize/services/symbol_link_test.dart b/test/lib/interpret_and_optimize/services/symbol_link_test.dart index 60f46b21..14311955 100644 --- a/test/lib/interpret_and_optimize/services/symbol_link_test.dart +++ b/test/lib/interpret_and_optimize/services/symbol_link_test.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/input/sketch/entities/layers/symbol_instance.dart'; import 'package:parabeac_core/input/sketch/entities/layers/symbol_master.dart'; @@ -8,7 +10,6 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.da import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:test/test.dart'; import 'package:mockito/mockito.dart'; diff --git a/test/lib/layouts/layout_generation_test.dart b/test/lib/layouts/layout_generation_test.dart index 9fadd7f9..afe35045 100644 --- a/test/lib/layouts/layout_generation_test.dart +++ b/test/lib/layouts/layout_generation_test.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:mockito/mockito.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; @@ -8,7 +10,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:test/test.dart'; class TempGroupMock extends Mock implements TempGroupLayoutNode {} diff --git a/test/lib/layouts/layout_post_rules_test.dart b/test/lib/layouts/layout_post_rules_test.dart index 0ec1d6d3..ad8d1c6d 100644 --- a/test/lib/layouts/layout_post_rules_test.dart +++ b/test/lib/layouts/layout_post_rules_test.dart @@ -1,10 +1,11 @@ +import 'dart:math'; + import 'package:mockito/mockito.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:test/test.dart'; class InheritedContainerMockWrapper extends Mock implements InheritedContainer { From 5de493c8af6a1885024b379e6c14828a21587ef2 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 5 Aug 2021 13:00:24 -0600 Subject: [PATCH 279/404] WIP - CREATED unit test for task (#476), verifying on the process the FileStructureStrategy is going to take when executing FileStructureCommands --- test/lib/generation/file_system_test.dart | 100 ++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/test/lib/generation/file_system_test.dart b/test/lib/generation/file_system_test.dart index f1a0eecc..9881c471 100644 --- a/test/lib/generation/file_system_test.dart +++ b/test/lib/generation/file_system_test.dart @@ -1,5 +1,34 @@ +import 'dart:io'; + +import 'package:mockito/mockito.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; +import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:test/test.dart'; +import 'package:path/path.dart' as p; + +class FileSystemAnalyzerMock extends Mock implements FileSystemAnalyzer {} + +class FileMock extends Mock implements File {} + +class PageWriterMock extends Mock implements PBPageWriter {} + +class ProjectMock extends Mock implements PBProject {} + +/// Its a [FileStructureStrategy] deticated for testing some of the methods for [FileStructureStrategy], as +/// I can not just use [Mock] on a particular methods [FileStructureStrategy.getFile]. +class FileStructureSystemMock extends FileStructureStrategy { + final FileMock file; + FileStructureSystemMock(String GENERATED_PROJECT_PATH, + PBPageWriter pageWriter, PBProject pbProject, this.file) + : super(GENERATED_PROJECT_PATH, pageWriter, pbProject); + + @override + File getFile(String directory, String name) => file; +} void main() { group( @@ -31,4 +60,75 @@ void main() { actualPBCExt, FileOwnership.PBC, existingFileExtension)); }); }); + + group( + '$FileStructureStrategy only re-writing files that are [${FileOwnership.PBC}] owned and only once for [${FileOwnership.DEV}]', + () { + final generatedProjectPath = '/GeneratedProjectPath/'; + FileSystemAnalyzer analyzer; + FileStructureStrategy fileStructureStrategy; + File fileMock; + + /// Simple function to [verify] the arguments or call count of calling + /// [File.writeAsStringSync]. + var commandVerification = (List paths) { + reset(fileMock); + paths.forEach((path) { + var baseName = p.basename(path); + var command = WriteScreenCommand( + 'UUID_$baseName', baseName, p.dirname(path), 'CODE_$baseName'); + fileStructureStrategy.commandCreated(command); + }); + return verify(fileMock.writeAsStringSync(any)); + }; + + var devFiles = [ + './some_dev_files/dev_file.dart', + './other_dev_files/main.dart', + './random_dev_files/readme.md', + './random_dev_files/.gitignore', + ]; + + var pbcFiles = [ + './files_to_replace/another_depth/screen_one.g.dart', + './files_to_replace/another_depth/screen_two.g.dart' + ]; + + /// Contains both the [devFiles] and the [pbcFiles]. + List existingFiles; + setUp(() { + /// Adding the [generatedProjectPath] to [devFiles] & [pbcFiles]. + var addingGenProjectPath = + (path) => p.normalize(p.join(generatedProjectPath, path)); + pbcFiles = pbcFiles.map(addingGenProjectPath).toList(); + devFiles = devFiles.map(addingGenProjectPath).toList(); + + existingFiles = pbcFiles + devFiles; + analyzer = FileSystemAnalyzerMock(); + + fileMock = FileMock(); + fileStructureStrategy = FileStructureSystemMock( + generatedProjectPath, PageWriterMock(), ProjectMock(), fileMock); + + when(analyzer.paths).thenReturn(pbcFiles); + when(analyzer.containsFile(any)).thenAnswer((realInvocation) => + existingFiles.contains(realInvocation.positionalArguments.first)); + }); + + test('$FileStructureStrategy replacing only [${FileOwnership.PBC}', () { + var verification = commandVerification(pbcFiles); + expect(verification.callCount, pbcFiles.length, + reason: + '$FileStructureStrategy did not replace the correct amount of files (${devFiles.length}), it only replaced ${verification.callCount}'); + }); + + test( + '$FileStructureStrategy not replacing [${FileOwnership.DEV}] owned files', + () { + var verification = commandVerification(devFiles); + expect(verification.callCount, 0, + reason: + '$FileStructureStrategy should not be able to replace the ${FileOwnership.DEV} files, which is doing.'); + }); + }); } From 10d7f766fbeb81c9b4a706603067eb5afe635d88 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 5 Aug 2021 19:01:48 -0600 Subject: [PATCH 280/404] REFACTORED some generation classes so the FileSystemAnalyzer being used in the Controller is passed down to FileStructureStrategy and tested the overall dot-g process. --- lib/controllers/controller.dart | 9 ++-- .../flutter_project_builder.dart | 20 +++---- .../bloc_file_structure_strategy.dart | 5 +- .../commands/write_screen_command.dart | 6 ++- .../flutter_file_structure_strategy.dart | 5 +- .../pb_file_structure_strategy.dart | 28 ++++++++-- .../provider_file_structure_strategy.dart | 5 +- .../riverpod_file_structure_strategy.dart | 7 +-- .../bloc_generation_configuration.dart | 2 +- .../pb_generation_configuration.dart | 5 +- .../provider_generation_configuration.dart | 2 +- .../riverpod_generation_configuration.dart | 2 +- .../stateful_generation_configuration.dart | 2 +- test/lib/generation/file_system_test.dart | 53 +++++++++++++------ 14 files changed, 103 insertions(+), 48 deletions(-) diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart index 1cd24100..ea85158c 100644 --- a/lib/controllers/controller.dart +++ b/lib/controllers/controller.dart @@ -61,11 +61,11 @@ abstract class Controller { } var fileSystemAnalyzer = FileSystemAnalyzer(processInfo.genProjectPath); fileSystemAnalyzer.addFileExtension('.dart'); - + if (!(await fileSystemAnalyzer.projectExist())) { await FlutterProjectBuilder.createFlutterProject(processInfo.projectName, projectDir: processInfo.outputPath); - } else{ + } else { indexFileFuture = fileSystemAnalyzer.indexProjectFiles(); } @@ -75,9 +75,8 @@ abstract class Controller { designProject, processInfo.projectName, processInfo.genProjectPath); var fpb = FlutterProjectBuilder( - MainInfo().configuration.generationConfiguration, - project: pbProject, - pageWriter: PBFlutterWriter()); + MainInfo().configuration.generationConfiguration, fileSystemAnalyzer, + project: pbProject, pageWriter: PBFlutterWriter()); await indexFileFuture; await fpb.genProjectFiles(processInfo.genProjectPath); diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index b1562748..ac247d1b 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:io'; +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:path/path.dart' as p; import 'package:archive/archive.dart'; @@ -38,14 +39,19 @@ class FlutterProjectBuilder { ///This is going to be defaulted to [GenerationConfiguration] if nothing else is specified. GenerationConfiguration generationConfiguration; + FileSystemAnalyzer fileSystemAnalyzer; + FlutterProjectBuilder( - this.generationConfiguration, { + this.generationConfiguration, + this.fileSystemAnalyzer, { this.project, this.pageWriter, }) { log = Logger(runtimeType.toString()); + fileSystemAnalyzer ??= FileSystemAnalyzer(project.projectAbsPath); generationConfiguration.pageWriter = pageWriter; + generationConfiguration.fileSystemAnalyzer = fileSystemAnalyzer; } /// Creating a Flutter project within the [projectDir] with the name of [flutterProjectName]. @@ -84,7 +90,8 @@ class FlutterProjectBuilder { /// The formatter is going to be running within `[projectPath]bin/*`, /// `[projectPath]lib/*`, and `[projectPath]test/*` by using `dart format`. /// There is an option to set to set the current working directory of as [projectDir], - static Future formatProject(String projectPath, {String projectDir}) { + static Future formatProject(String projectPath, + {String projectDir}) { return Process.run( 'dart', [ @@ -104,7 +111,6 @@ class FlutterProjectBuilder { Future genProjectFiles(String genProjectPath, {List rawImages}) async { - if (MainInfo().figmaProjectID != null && MainInfo().figmaProjectID.isNotEmpty) { log.info('Processing remaining images...'); @@ -152,13 +158,9 @@ class FlutterProjectBuilder { await Future.wait(PBStateManagementLinker().stateQueue, eagerError: true); await generationConfiguration.generateProject(project); - await generationConfiguration - .generatePlatformAndOrientationInstance(project); - + generationConfiguration.generatePlatformAndOrientationInstance(project); - Process.runSync( - 'rm', - ['-rf', '.dart_tool/build'], + Process.runSync('rm', ['-rf', '.dart_tool/build'], runInShell: true, environment: Platform.environment, workingDirectory: MainInfo().outputPath); diff --git a/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart index 41e5f26a..87dd66cf 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; @@ -6,6 +7,6 @@ class BLoCFileStructureStrategy extends FileStructureStrategy { final RELATIVE_BLOC_PATH = 'lib/blocs'; BLoCFileStructureStrategy( - String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) - : super(genProjectPath, pageWriter, pbProject); + String genProjectPath, PBPageWriter pageWriter, PBProject pbProject, FileSystemAnalyzer fileSystemAnalyzer) + : super(genProjectPath, pageWriter, pbProject, fileSystemAnalyzer); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart index 697b270e..6c8a9bf5 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart @@ -7,11 +7,13 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure class WriteScreenCommand extends NodeFileStructureCommand { String name; String relativePath; + String fileExtension; static final SCREEN_PATH = 'lib/screens'; WriteScreenCommand(String UUID, this.name, this.relativePath, String code, - {FileOwnership ownership = FileOwnership.PBC}) + {FileOwnership ownership = FileOwnership.PBC, + this.fileExtension = '.dart'}) : super(UUID, code, ownership); /// Writes a screen file containing [code] to [path] with [name] as its filename. @@ -22,7 +24,7 @@ class WriteScreenCommand extends NodeFileStructureCommand { var absPath = p.join(strategy.GENERATED_PROJECT_PATH, SCREEN_PATH, relativePath); strategy.writeDataToFile(code, absPath, name, - UUID: UUID, ownership: ownership); + UUID: UUID, ownership: ownership, ext: fileExtension); return Future.value(p.join(absPath, name)); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart index 246306e5..4695bb1e 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/flutter_file_structure_strategy.dart @@ -1,9 +1,10 @@ +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; class FlutterFileStructureStrategy extends FileStructureStrategy { FlutterFileStructureStrategy( - String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) - : super(genProjectPath, pageWriter, pbProject); + String genProjectPath, PBPageWriter pageWriter, PBProject pbProject, FileSystemAnalyzer fileSystemAnalyzer) + : super(genProjectPath, pageWriter, pbProject, fileSystemAnalyzer); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index c578da22..018fed5c 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:path/path.dart' as p; @@ -20,7 +21,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod ///while something like BLoC will assign a directory to a single. /// abstract class FileStructureStrategy implements CommandInvoker { - final Logger logger = Logger('FileStructureStrategy'); + Logger logger; ///The `default` path of where all the views are going to be generated. /// @@ -70,12 +71,25 @@ abstract class FileStructureStrategy implements CommandInvoker { /// the [File]. FileOwnershipPolicy fileOwnershipPolicy; + /// Uses the [FileSystemAnalyzer] to see if certain [File]s aready exist in the file system. + /// + /// This is primarly used when checking [FileOwnership.DEV]'s [File]s in the files sytem to see if they exist. + /// If they do exist, then PBC is not going to modify them, ignoring whatever modification towards the [File] + /// that was comming through [writeDataToFile] (method that created the actual [File]s). + FileSystemAnalyzer _fileSystemAnalyzer; + String _screenDirectoryPath; String _viewDirectoryPath; - FileStructureStrategy( - this.GENERATED_PROJECT_PATH, this._pageWriter, this._pbProject, + FileStructureStrategy(this.GENERATED_PROJECT_PATH, this._pageWriter, + this._pbProject, this._fileSystemAnalyzer, {this.fileOwnershipPolicy}) { + logger = Logger(runtimeType.toString()); + if (_fileSystemAnalyzer == null) { + logger.error( + '$FileSystemAnalyzer is null, meaning there are no files indexed and all files are going to be created.'); + _fileSystemAnalyzer = FileSystemAnalyzer(GENERATED_PROJECT_PATH); + } fileOwnershipPolicy ??= DotGFileOwnershipPolicy(); } @@ -170,6 +184,14 @@ abstract class FileStructureStrategy implements CommandInvoker { p.setExtension( name, fileOwnershipPolicy.getFileExtension(ownership, ext))); + if (_fileSystemAnalyzer.containsFile(file.path) && + ownership == FileOwnership.DEV) { + /// file is going to be ignored + logger.fine( + 'File $name has been ignored as is already present in the project'); + return; + } + if (!dryRunMode) { file.createSync(recursive: true); file.writeAsStringSync(data); diff --git a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart index 251db68a..0d51a202 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; @@ -10,8 +11,8 @@ class ProviderFileStructureStrategy extends FileStructureStrategy { var _modelsPath; ProviderFileStructureStrategy( - String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) - : super(genProjectPath, pageWriter, pbProject) { + String genProjectPath, PBPageWriter pageWriter, PBProject pbProject, FileSystemAnalyzer fileSystemAnalyzer) + : super(genProjectPath, pageWriter, pbProject, fileSystemAnalyzer) { _modelsPath = p.join(genProjectPath, RELATIVE_MODEL_PATH); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart index a08f2013..01490004 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -11,9 +12,9 @@ class RiverpodFileStructureStrategy extends FileStructureStrategy { var _providersPath; var _modelsPath; - RiverpodFileStructureStrategy( - String genProjectPath, PBPageWriter pageWriter, PBProject pbProject) - : super(genProjectPath, pageWriter, pbProject) { + RiverpodFileStructureStrategy(String genProjectPath, PBPageWriter pageWriter, + PBProject pbProject, FileSystemAnalyzer fileSystemAnalyzer) + : super(genProjectPath, pageWriter, pbProject, fileSystemAnalyzer) { _providersPath = p.join(genProjectPath, RELATIVE_PROVIDER_PATH); _modelsPath = p.join(genProjectPath, RELATIVE_MODEL_PATH); } diff --git a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart index 1f3732e1..0f7a3970 100644 --- a/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/bloc_generation_configuration.dart @@ -13,7 +13,7 @@ class BLoCGenerationConfiguration extends GenerationConfiguration { logger.info( 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); fileStructureStrategy = BLoCFileStructureStrategy( - pbProject.projectAbsPath, pageWriter, pbProject); + pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); registerMiddleware(BLoCMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 5b1d6885..cfed23b8 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/command_gen_middleware.dart'; @@ -63,6 +64,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { /// Those [FileStructureCommand]s could just be added to the list. final List commandQueue = []; + FileSystemAnalyzer fileSystemAnalyzer; + GenerationConfiguration() { logger = Logger(runtimeType.toString()); _importProcessor ??= ImportHelper(); @@ -150,7 +153,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ///Configure the required classes for the [PBGenerationConfiguration] Future setUpConfiguration(PBProject pbProject) async { fileStructureStrategy = FlutterFileStructureStrategy( - pbProject.projectAbsPath, pageWriter, pbProject); + pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); commandObservers.add(fileStructureStrategy); logger.info('Setting up the directories'); diff --git a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart index bdd87386..576bd507 100644 --- a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart @@ -19,7 +19,7 @@ class ProviderGenerationConfiguration extends GenerationConfiguration { logger.info( 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); fileStructureStrategy = ProviderFileStructureStrategy( - pbProject.projectAbsPath, pageWriter, pbProject); + pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); registerMiddleware(ProviderMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); diff --git a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart index 7f039b87..3cbc53b9 100644 --- a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart @@ -16,7 +16,7 @@ class RiverpodGenerationConfiguration extends GenerationConfiguration { logger.info( 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); fileStructureStrategy = RiverpodFileStructureStrategy( - pbProject.projectAbsPath, pageWriter, pbProject); + pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); registerMiddleware(RiverpodMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); diff --git a/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart index 7afa7978..bd04b90f 100644 --- a/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/stateful_generation_configuration.dart @@ -8,7 +8,7 @@ class StatefulGenerationConfiguration extends GenerationConfiguration { @override Future setUpConfiguration(pbProject) async { fileStructureStrategy = FlutterFileStructureStrategy( - pbProject.projectAbsPath, pageWriter, pbProject); + pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); registerMiddleware(StatefulMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); diff --git a/test/lib/generation/file_system_test.dart b/test/lib/generation/file_system_test.dart index 9881c471..b09e490e 100644 --- a/test/lib/generation/file_system_test.dart +++ b/test/lib/generation/file_system_test.dart @@ -12,7 +12,10 @@ import 'package:path/path.dart' as p; class FileSystemAnalyzerMock extends Mock implements FileSystemAnalyzer {} -class FileMock extends Mock implements File {} +class FileMock extends Mock implements File { + @override + String path; +} class PageWriterMock extends Mock implements PBPageWriter {} @@ -22,12 +25,17 @@ class ProjectMock extends Mock implements PBProject {} /// I can not just use [Mock] on a particular methods [FileStructureStrategy.getFile]. class FileStructureSystemMock extends FileStructureStrategy { final FileMock file; + final FileSystemAnalyzer analyzer; + String path; FileStructureSystemMock(String GENERATED_PROJECT_PATH, - PBPageWriter pageWriter, PBProject pbProject, this.file) - : super(GENERATED_PROJECT_PATH, pageWriter, pbProject); + PBPageWriter pageWriter, PBProject pbProject, this.file, this.analyzer) + : super(GENERATED_PROJECT_PATH, pageWriter, pbProject, analyzer); @override - File getFile(String directory, String name) => file; + File getFile(String directory, String name) { + file.path = p.join(directory, name); + return file; + } } void main() { @@ -71,15 +79,29 @@ void main() { /// Simple function to [verify] the arguments or call count of calling /// [File.writeAsStringSync]. - var commandVerification = (List paths) { + /// + /// Because of no calls to a method and calling [verify] will cause an error, therefore, + /// if the caller of the [commandVerification] funciton expects no calls, then it would have to pass + /// `true` for [noCalls]. This flag will force the function to call [verifyNever] instead of [verify] + var commandVerification = + (List paths, FileOwnership ownership, {bool noCalls = false}) { reset(fileMock); paths.forEach((path) { var baseName = p.basename(path); - var command = WriteScreenCommand( - 'UUID_$baseName', baseName, p.dirname(path), 'CODE_$baseName'); + var ext = p.extension(path); + + /// Files like `.gitignore` are going to be evaluated to [ext.isEmpty] by [p.extension], + /// therefore, I am padding the [baseName] + ext = ext.isEmpty ? baseName : ext; + + var command = WriteScreenCommand('UUID_$baseName', + baseName == ext ? '' : baseName, p.dirname(path), 'CODE_$baseName', + ownership: ownership, fileExtension: ext); fileStructureStrategy.commandCreated(command); }); - return verify(fileMock.writeAsStringSync(any)); + return noCalls + ? verifyNever(fileMock.writeAsStringSync(any)) + : verify(fileMock.writeAsStringSync(any)); }; var devFiles = [ @@ -107,16 +129,16 @@ void main() { analyzer = FileSystemAnalyzerMock(); fileMock = FileMock(); - fileStructureStrategy = FileStructureSystemMock( - generatedProjectPath, PageWriterMock(), ProjectMock(), fileMock); + fileStructureStrategy = FileStructureSystemMock(generatedProjectPath, + PageWriterMock(), ProjectMock(), fileMock, analyzer); - when(analyzer.paths).thenReturn(pbcFiles); + when(analyzer.paths).thenReturn(existingFiles); when(analyzer.containsFile(any)).thenAnswer((realInvocation) => existingFiles.contains(realInvocation.positionalArguments.first)); }); - test('$FileStructureStrategy replacing only [${FileOwnership.PBC}', () { - var verification = commandVerification(pbcFiles); + test('$FileStructureStrategy replacing only [${FileOwnership.PBC}]', () { + var verification = commandVerification(pbcFiles, FileOwnership.PBC); expect(verification.callCount, pbcFiles.length, reason: '$FileStructureStrategy did not replace the correct amount of files (${devFiles.length}), it only replaced ${verification.callCount}'); @@ -125,10 +147,11 @@ void main() { test( '$FileStructureStrategy not replacing [${FileOwnership.DEV}] owned files', () { - var verification = commandVerification(devFiles); + var verification = + commandVerification(devFiles, FileOwnership.DEV, noCalls: true); expect(verification.callCount, 0, reason: - '$FileStructureStrategy should not be able to replace the ${FileOwnership.DEV} files, which is doing.'); + '$FileStructureStrategy should not be able to replace the ${FileOwnership.DEV} files, which its doing.'); }); }); } From 51e62d436c8e1bda4fdd1edb1ed3b3d955afcc82 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Mon, 9 Aug 2021 13:58:32 -0600 Subject: [PATCH 281/404] MERGED PBDL branch into responsive UI --- .gitmodules | 7 +- SketchAssetConverter | 1 - lib/controllers/design_controller.dart | 30 -- lib/controllers/figma_controller.dart | 95 ------ lib/controllers/interpret.dart | 81 ++--- lib/controllers/main_info.dart | 33 +- lib/controllers/sketch_controller.dart | 96 ------ .../abstract_design_node_factory.dart | 58 ---- lib/design_logic/artboard.dart | 129 -------- lib/design_logic/boolean_operation.dart | 99 ------ lib/design_logic/color.dart | 45 --- lib/design_logic/design_element.dart | 21 -- lib/design_logic/design_node.dart | 38 --- lib/design_logic/design_shape.dart | 5 - lib/design_logic/group_node.dart | 139 -------- lib/design_logic/image.dart | 121 ------- lib/design_logic/oval.dart | 123 ------- lib/design_logic/pb_border.dart | 17 - lib/design_logic/pb_border_options.dart | 14 - lib/design_logic/pb_fill.dart | 11 - lib/design_logic/pb_font_descriptor.dart | 5 - lib/design_logic/pb_paragraph_style.dart | 10 - .../pb_shared_instance_design_node.dart | 132 -------- lib/design_logic/pb_shared_master_node.dart | 181 ---------- lib/design_logic/pb_style.dart | 30 -- lib/design_logic/pb_text_style.dart | 19 -- lib/design_logic/polygon.dart | 124 ------- lib/design_logic/rect.dart | 13 - lib/design_logic/rectangle.dart | 158 --------- lib/design_logic/star.dart | 123 ------- lib/design_logic/text.dart | 127 ------- lib/design_logic/vector.dart | 133 -------- lib/eggs/custom_egg.dart | 7 +- lib/eggs/injected_app_bar.dart | 24 +- lib/eggs/injected_back_arrow.dart | 7 +- lib/eggs/injected_tab.dart | 58 ++-- lib/eggs/injected_tab_bar.dart | 10 +- .../flutter_project_builder.dart | 72 ++-- .../import_helper.dart | 75 ++--- .../pb_box_decoration_gen_helper.dart | 20 +- .../attribute-helper/pb_color_gen_helper.dart | 99 ++---- .../utils/middleware_utils.dart | 7 +- .../generators/plugins/pb_plugin_node.dart | 7 +- .../symbols/pb_instancesym_gen.dart | 129 +++----- .../pb_generation_configuration.dart | 4 +- .../stateless_template_strategy.dart | 5 +- .../visual-widgets/pb_align_gen.dart | 37 +++ .../visual-widgets/pb_bitmap_gen.dart | 24 +- .../visual-widgets/pb_container_gen.dart | 3 +- .../visual-widgets/pb_flexible_gen.dart | 4 +- .../visual-widgets/pb_text_gen.dart | 24 +- .../pb_prototype_aggregation_service.dart | 32 +- .../prototyping/pb_prototype_node.dart | 6 +- lib/input/assets/image-conversion-error.png | Bin 16739 -> 0 bytes .../entities/abstract_figma_node_factory.dart | 56 ---- .../entities/layers/boolean_operation.dart | 78 ----- .../entities/layers/boolean_operation.g.dart | 71 ---- lib/input/figma/entities/layers/canvas.dart | 98 ------ lib/input/figma/entities/layers/canvas.g.dart | 50 --- .../figma/entities/layers/component.dart | 154 --------- .../figma/entities/layers/component.g.dart | 83 ----- lib/input/figma/entities/layers/ellipse.dart | 113 ------- .../figma/entities/layers/ellipse.g.dart | 63 ---- .../layers/figma_font_descriptor.dart | 27 -- .../figma/entities/layers/figma_node.dart | 53 --- .../layers/figma_paragraph_style.dart | 8 - lib/input/figma/entities/layers/frame.dart | 190 ----------- lib/input/figma/entities/layers/frame.g.dart | 78 ----- lib/input/figma/entities/layers/group.dart | 191 ----------- lib/input/figma/entities/layers/group.g.dart | 77 ----- lib/input/figma/entities/layers/instance.dart | 137 -------- .../figma/entities/layers/instance.g.dart | 83 ----- lib/input/figma/entities/layers/line.dart | 105 ------ lib/input/figma/entities/layers/line.g.dart | 62 ---- .../figma/entities/layers/rectangle.dart | 160 --------- .../figma/entities/layers/rectangle.g.dart | 71 ---- .../entities/layers/regular_polygon.dart | 107 ------ .../entities/layers/regular_polygon.g.dart | 64 ---- lib/input/figma/entities/layers/slice.dart | 98 ------ lib/input/figma/entities/layers/slice.g.dart | 49 --- lib/input/figma/entities/layers/star.dart | 103 ------ lib/input/figma/entities/layers/star.g.dart | 62 ---- lib/input/figma/entities/layers/text.dart | 152 --------- lib/input/figma/entities/layers/text.g.dart | 86 ----- lib/input/figma/entities/layers/vector.dart | 129 -------- lib/input/figma/entities/layers/vector.g.dart | 65 ---- .../figma/entities/style/figma_border.dart | 30 -- .../figma/entities/style/figma_border.g.dart | 26 -- .../entities/style/figma_border_options.dart | 34 -- .../style/figma_border_options.g.dart | 24 -- .../figma/entities/style/figma_color.dart | 31 -- .../figma/entities/style/figma_color.g.dart | 24 -- .../figma/entities/style/figma_fill.dart | 24 -- .../figma/entities/style/figma_fill.g.dart | 22 -- .../figma/entities/style/figma_style.dart | 50 --- .../figma/entities/style/figma_style.g.dart | 39 --- .../entities/style/figma_text_style.dart | 39 --- .../entities/style/figma_text_style.g.dart | 22 -- lib/input/figma/helper/api_call_service.dart | 92 ------ lib/input/figma/helper/api_exceptions.dart | 26 -- .../figma/helper/figma_asset_processor.dart | 135 -------- lib/input/figma/helper/figma_page.dart | 12 - lib/input/figma/helper/figma_project.dart | 63 ---- lib/input/figma/helper/figma_screen.dart | 15 - lib/input/figma/helper/style_extractor.dart | 140 -------- .../helper/asset_processing_service.dart | 34 -- lib/input/helper/azure_asset_service.dart | 78 ----- lib/input/helper/design_page.dart | 68 ---- lib/input/helper/design_project.dart | 90 ----- lib/input/helper/design_screen.dart | 61 ---- .../abstract_sketch_node_factory.dart | 61 ---- .../entities/documents/abstract_document.dart | 33 -- .../sketch/entities/documents/document.dart | 44 --- .../sketch/entities/documents/document.g.dart | 47 --- .../entities/layers/abstract_group_layer.dart | 76 ----- .../entities/layers/abstract_layer.dart | 84 ----- .../entities/layers/abstract_shape_layer.dart | 69 ---- .../sketch/entities/layers/artboard.dart | 221 ------------- .../sketch/entities/layers/artboard.g.dart | 107 ------ lib/input/sketch/entities/layers/bitmap.dart | 200 ----------- .../sketch/entities/layers/bitmap.g.dart | 81 ----- lib/input/sketch/entities/layers/flow.dart | 20 -- lib/input/sketch/entities/layers/flow.g.dart | 23 -- lib/input/sketch/entities/layers/group.dart | 182 ---------- lib/input/sketch/entities/layers/group.g.dart | 84 ----- lib/input/sketch/entities/layers/oval.dart | 171 ---------- lib/input/sketch/entities/layers/oval.g.dart | 81 ----- lib/input/sketch/entities/layers/page.dart | 182 ---------- lib/input/sketch/entities/layers/page.g.dart | 92 ------ lib/input/sketch/entities/layers/polygon.dart | 173 ---------- .../sketch/entities/layers/polygon.g.dart | 81 ----- .../sketch/entities/layers/rectangle.dart | 199 ----------- .../sketch/entities/layers/rectangle.g.dart | 90 ----- .../sketch/entities/layers/shape_group.dart | 187 ----------- .../sketch/entities/layers/shape_group.g.dart | 85 ----- .../sketch/entities/layers/shape_path.dart | 170 ---------- .../sketch/entities/layers/shape_path.g.dart | 81 ----- .../sketch/entities/layers/sketch_text.dart | 233 ------------- .../sketch/entities/layers/sketch_text.g.dart | 88 ----- lib/input/sketch/entities/layers/star.dart | 174 ---------- lib/input/sketch/entities/layers/star.g.dart | 81 ----- .../entities/layers/symbol_instance.dart | 215 ------------ .../entities/layers/symbol_instance.g.dart | 90 ----- .../sketch/entities/layers/symbol_master.dart | 265 --------------- .../entities/layers/symbol_master.g.dart | 128 -------- .../sketch/entities/layers/triangle.dart | 172 ---------- .../sketch/entities/layers/triangle.g.dart | 81 ----- .../entities/objects/foreign_symbol.dart | 28 -- .../entities/objects/foreign_symbol.g.dart | 32 -- lib/input/sketch/entities/objects/frame.dart | 23 -- .../sketch/entities/objects/frame.g.dart | 27 -- .../entities/objects/override_property.dart | 18 - .../entities/objects/override_property.g.dart | 21 -- .../entities/objects/override_value.dart | 20 -- .../entities/objects/override_value.g.dart | 22 -- lib/input/sketch/entities/style/blur.dart | 16 - lib/input/sketch/entities/style/blur.g.dart | 29 -- lib/input/sketch/entities/style/border.dart | 37 --- lib/input/sketch/entities/style/border.g.dart | 38 --- .../sketch/entities/style/border_options.dart | 27 -- .../entities/style/border_options.g.dart | 26 -- lib/input/sketch/entities/style/color.dart | 18 - lib/input/sketch/entities/style/color.g.dart | 25 -- .../sketch/entities/style/color_controls.dart | 15 - .../entities/style/color_controls.g.dart | 28 -- .../entities/style/context_settings.dart | 14 - .../entities/style/context_settings.g.dart | 22 -- lib/input/sketch/entities/style/fill.dart | 41 --- lib/input/sketch/entities/style/fill.g.dart | 42 --- .../entities/style/font_descriptor.dart | 32 -- .../entities/style/font_descriptor.g.dart | 18 - lib/input/sketch/entities/style/gradient.dart | 25 -- .../sketch/entities/style/gradient.g.dart | 30 -- .../sketch/entities/style/gradient_stop.dart | 16 - .../entities/style/gradient_stop.g.dart | 24 -- .../entities/style/paragraph_style.dart | 16 - .../entities/style/paragraph_style.g.dart | 18 - .../sketch/entities/style/shared_style.dart | 135 -------- .../sketch/entities/style/shared_style.g.dart | 26 -- lib/input/sketch/entities/style/style.dart | 87 ----- lib/input/sketch/entities/style/style.g.dart | 68 ---- .../sketch/entities/style/text_style.dart | 119 ------- .../sketch/entities/style/text_style.g.dart | 25 -- .../sketch/helper/sketch_asset_processor.dart | 77 ----- lib/input/sketch/helper/sketch_page.dart | 13 - lib/input/sketch/helper/sketch_project.dart | 150 --------- lib/input/sketch/helper/sketch_screen.dart | 16 - .../sketch/helper/symbol_node_mixin.dart | 104 ------ lib/input/sketch/services/input_design.dart | 64 ---- .../positional_cleansing_service.dart | 30 -- .../entities/alignments/flexible.dart | 3 + .../entities/alignments/injected_align.dart | 72 ++++ .../alignments/injected_positioned.dart | 2 + .../entities/alignments/padding.dart | 2 + .../entities/alignments/spacer.dart | 3 + .../entities/inherited_bitmap.dart | 97 +++--- .../entities/inherited_bitmap.g.dart | 47 +++ .../entities/inherited_circle.dart | 114 ++++++- .../entities/inherited_circle.g.dart | 45 +++ .../entities/inherited_container.dart | 135 ++++---- .../entities/inherited_container.g.dart | 41 +++ .../entities/inherited_oval.dart | 85 +++-- .../entities/inherited_oval.g.dart | 45 +++ .../entities/inherited_polygon.dart | 93 ++++-- .../entities/inherited_polygon.g.dart | 45 +++ .../entities/inherited_scaffold.dart | 113 +++++-- .../entities/inherited_scaffold.g.dart | 37 +++ .../entities/inherited_shape_group.dart | 102 ++++-- .../entities/inherited_shape_group.g.dart | 40 +++ .../entities/inherited_shape_path.dart | 143 ++++---- .../entities/inherited_shape_path.g.dart | 45 +++ .../entities/inherited_star.dart | 96 +++++- .../entities/inherited_star.g.dart | 45 +++ .../entities/inherited_text.dart | 175 +++++++--- .../entities/inherited_text.g.dart | 49 +++ .../entities/inherited_triangle.dart | 91 +++-- .../entities/inherited_triangle.g.dart | 45 +++ .../entities/injected_container.dart | 64 +++- .../entities/injected_container.g.dart | 50 +++ .../interfaces/pb_inherited_intermediate.dart | 12 +- .../entities/intermediate_border_info.dart | 34 ++ .../entities/intermediate_border_info.g.dart | 30 ++ .../entities/layouts/column.dart | 3 + .../entities/layouts/row.dart | 17 + .../entities/layouts/rules/handle_flex.dart | 4 +- .../entities/layouts/stack.dart | 3 + .../layouts/temp_group_layout_node.dart | 75 ++++- .../layouts/temp_group_layout_node.g.dart | 40 +++ .../entities/pb_deny_list_node.dart | 18 +- .../entities/pb_shared_instance.dart | 150 ++++++--- .../entities/pb_shared_instance.g.dart | 75 +++++ .../entities/pb_shared_master_node.dart | 189 +++++++---- .../entities/pb_shared_master_node.g.dart | 69 ++++ .../subclasses/pb_intermediate_node.dart | 43 ++- .../subclasses/pb_intermediate_node.g.dart | 20 ++ .../abstract_intermediate_node_factory.dart | 88 +++++ .../helpers/index_walker.dart | 12 + .../helpers/node_tuple.dart | 22 +- .../helpers/override_helper.dart | 30 ++ .../helpers/pb_color.dart | 72 ++++ .../helpers/pb_color.g.dart | 23 ++ .../helpers/pb_deny_list_helper.dart | 9 +- .../helpers/pb_intermediate_node_tree.dart | 52 ++- .../helpers/pb_intermediate_node_tree.g.dart | 21 ++ .../helpers/pb_plugin_list_helper.dart | 39 ++- .../helpers/pb_project.dart | 49 ++- .../helpers/pb_project.g.dart | 21 ++ .../helpers/pb_state_management_linker.dart | 4 +- .../helpers/pb_symbol_storage.dart | 8 +- .../design_to_pbdl_service.dart | 8 + .../design_to_pbdl/figma_to_pbdl_service.dart | 16 + .../sketch_to_pbdl_service.dart | 17 + .../pb_semantic_generation_service.dart | 64 ++-- .../pb_shared_aggregation_service.dart | 19 +- .../services/pb_symbol_linker_service.dart | 24 +- .../pb_visual_generation_service.dart | 310 +++++++++--------- .../intermediate_auxillary_data.dart | 28 +- .../intermediate_auxillary_data.g.dart | 23 ++ .../pb_symbol_instance_overridable_value.dart | 16 - lib/main.dart | 48 ++- pbdl | 1 + pubspec.yaml | 7 +- 262 files changed, 3245 insertions(+), 13579 deletions(-) delete mode 160000 SketchAssetConverter delete mode 100644 lib/controllers/design_controller.dart delete mode 100644 lib/controllers/figma_controller.dart delete mode 100644 lib/controllers/sketch_controller.dart delete mode 100644 lib/design_logic/abstract_design_node_factory.dart delete mode 100644 lib/design_logic/artboard.dart delete mode 100644 lib/design_logic/boolean_operation.dart delete mode 100644 lib/design_logic/color.dart delete mode 100644 lib/design_logic/design_element.dart delete mode 100644 lib/design_logic/design_node.dart delete mode 100644 lib/design_logic/design_shape.dart delete mode 100644 lib/design_logic/group_node.dart delete mode 100644 lib/design_logic/image.dart delete mode 100644 lib/design_logic/oval.dart delete mode 100644 lib/design_logic/pb_border.dart delete mode 100644 lib/design_logic/pb_border_options.dart delete mode 100644 lib/design_logic/pb_fill.dart delete mode 100644 lib/design_logic/pb_font_descriptor.dart delete mode 100644 lib/design_logic/pb_paragraph_style.dart delete mode 100644 lib/design_logic/pb_shared_instance_design_node.dart delete mode 100644 lib/design_logic/pb_shared_master_node.dart delete mode 100644 lib/design_logic/pb_style.dart delete mode 100644 lib/design_logic/pb_text_style.dart delete mode 100644 lib/design_logic/polygon.dart delete mode 100644 lib/design_logic/rect.dart delete mode 100644 lib/design_logic/rectangle.dart delete mode 100644 lib/design_logic/star.dart delete mode 100644 lib/design_logic/text.dart delete mode 100644 lib/design_logic/vector.dart create mode 100644 lib/generation/generators/visual-widgets/pb_align_gen.dart delete mode 100644 lib/input/assets/image-conversion-error.png delete mode 100644 lib/input/figma/entities/abstract_figma_node_factory.dart delete mode 100644 lib/input/figma/entities/layers/boolean_operation.dart delete mode 100644 lib/input/figma/entities/layers/boolean_operation.g.dart delete mode 100644 lib/input/figma/entities/layers/canvas.dart delete mode 100644 lib/input/figma/entities/layers/canvas.g.dart delete mode 100644 lib/input/figma/entities/layers/component.dart delete mode 100644 lib/input/figma/entities/layers/component.g.dart delete mode 100644 lib/input/figma/entities/layers/ellipse.dart delete mode 100644 lib/input/figma/entities/layers/ellipse.g.dart delete mode 100644 lib/input/figma/entities/layers/figma_font_descriptor.dart delete mode 100644 lib/input/figma/entities/layers/figma_node.dart delete mode 100644 lib/input/figma/entities/layers/figma_paragraph_style.dart delete mode 100644 lib/input/figma/entities/layers/frame.dart delete mode 100644 lib/input/figma/entities/layers/frame.g.dart delete mode 100644 lib/input/figma/entities/layers/group.dart delete mode 100644 lib/input/figma/entities/layers/group.g.dart delete mode 100644 lib/input/figma/entities/layers/instance.dart delete mode 100644 lib/input/figma/entities/layers/instance.g.dart delete mode 100644 lib/input/figma/entities/layers/line.dart delete mode 100644 lib/input/figma/entities/layers/line.g.dart delete mode 100644 lib/input/figma/entities/layers/rectangle.dart delete mode 100644 lib/input/figma/entities/layers/rectangle.g.dart delete mode 100644 lib/input/figma/entities/layers/regular_polygon.dart delete mode 100644 lib/input/figma/entities/layers/regular_polygon.g.dart delete mode 100644 lib/input/figma/entities/layers/slice.dart delete mode 100644 lib/input/figma/entities/layers/slice.g.dart delete mode 100644 lib/input/figma/entities/layers/star.dart delete mode 100644 lib/input/figma/entities/layers/star.g.dart delete mode 100644 lib/input/figma/entities/layers/text.dart delete mode 100644 lib/input/figma/entities/layers/text.g.dart delete mode 100644 lib/input/figma/entities/layers/vector.dart delete mode 100644 lib/input/figma/entities/layers/vector.g.dart delete mode 100644 lib/input/figma/entities/style/figma_border.dart delete mode 100644 lib/input/figma/entities/style/figma_border.g.dart delete mode 100644 lib/input/figma/entities/style/figma_border_options.dart delete mode 100644 lib/input/figma/entities/style/figma_border_options.g.dart delete mode 100644 lib/input/figma/entities/style/figma_color.dart delete mode 100644 lib/input/figma/entities/style/figma_color.g.dart delete mode 100644 lib/input/figma/entities/style/figma_fill.dart delete mode 100644 lib/input/figma/entities/style/figma_fill.g.dart delete mode 100644 lib/input/figma/entities/style/figma_style.dart delete mode 100644 lib/input/figma/entities/style/figma_style.g.dart delete mode 100644 lib/input/figma/entities/style/figma_text_style.dart delete mode 100644 lib/input/figma/entities/style/figma_text_style.g.dart delete mode 100644 lib/input/figma/helper/api_call_service.dart delete mode 100644 lib/input/figma/helper/api_exceptions.dart delete mode 100644 lib/input/figma/helper/figma_asset_processor.dart delete mode 100644 lib/input/figma/helper/figma_page.dart delete mode 100644 lib/input/figma/helper/figma_project.dart delete mode 100644 lib/input/figma/helper/figma_screen.dart delete mode 100644 lib/input/figma/helper/style_extractor.dart delete mode 100644 lib/input/helper/asset_processing_service.dart delete mode 100644 lib/input/helper/azure_asset_service.dart delete mode 100644 lib/input/helper/design_page.dart delete mode 100644 lib/input/helper/design_project.dart delete mode 100644 lib/input/helper/design_screen.dart delete mode 100644 lib/input/sketch/entities/abstract_sketch_node_factory.dart delete mode 100644 lib/input/sketch/entities/documents/abstract_document.dart delete mode 100644 lib/input/sketch/entities/documents/document.dart delete mode 100644 lib/input/sketch/entities/documents/document.g.dart delete mode 100644 lib/input/sketch/entities/layers/abstract_group_layer.dart delete mode 100644 lib/input/sketch/entities/layers/abstract_layer.dart delete mode 100644 lib/input/sketch/entities/layers/abstract_shape_layer.dart delete mode 100644 lib/input/sketch/entities/layers/artboard.dart delete mode 100644 lib/input/sketch/entities/layers/artboard.g.dart delete mode 100644 lib/input/sketch/entities/layers/bitmap.dart delete mode 100644 lib/input/sketch/entities/layers/bitmap.g.dart delete mode 100644 lib/input/sketch/entities/layers/flow.dart delete mode 100644 lib/input/sketch/entities/layers/flow.g.dart delete mode 100644 lib/input/sketch/entities/layers/group.dart delete mode 100644 lib/input/sketch/entities/layers/group.g.dart delete mode 100644 lib/input/sketch/entities/layers/oval.dart delete mode 100644 lib/input/sketch/entities/layers/oval.g.dart delete mode 100644 lib/input/sketch/entities/layers/page.dart delete mode 100644 lib/input/sketch/entities/layers/page.g.dart delete mode 100644 lib/input/sketch/entities/layers/polygon.dart delete mode 100644 lib/input/sketch/entities/layers/polygon.g.dart delete mode 100644 lib/input/sketch/entities/layers/rectangle.dart delete mode 100644 lib/input/sketch/entities/layers/rectangle.g.dart delete mode 100644 lib/input/sketch/entities/layers/shape_group.dart delete mode 100644 lib/input/sketch/entities/layers/shape_group.g.dart delete mode 100644 lib/input/sketch/entities/layers/shape_path.dart delete mode 100644 lib/input/sketch/entities/layers/shape_path.g.dart delete mode 100644 lib/input/sketch/entities/layers/sketch_text.dart delete mode 100644 lib/input/sketch/entities/layers/sketch_text.g.dart delete mode 100644 lib/input/sketch/entities/layers/star.dart delete mode 100644 lib/input/sketch/entities/layers/star.g.dart delete mode 100644 lib/input/sketch/entities/layers/symbol_instance.dart delete mode 100644 lib/input/sketch/entities/layers/symbol_instance.g.dart delete mode 100644 lib/input/sketch/entities/layers/symbol_master.dart delete mode 100644 lib/input/sketch/entities/layers/symbol_master.g.dart delete mode 100644 lib/input/sketch/entities/layers/triangle.dart delete mode 100644 lib/input/sketch/entities/layers/triangle.g.dart delete mode 100644 lib/input/sketch/entities/objects/foreign_symbol.dart delete mode 100644 lib/input/sketch/entities/objects/foreign_symbol.g.dart delete mode 100644 lib/input/sketch/entities/objects/frame.dart delete mode 100644 lib/input/sketch/entities/objects/frame.g.dart delete mode 100644 lib/input/sketch/entities/objects/override_property.dart delete mode 100644 lib/input/sketch/entities/objects/override_property.g.dart delete mode 100644 lib/input/sketch/entities/objects/override_value.dart delete mode 100644 lib/input/sketch/entities/objects/override_value.g.dart delete mode 100644 lib/input/sketch/entities/style/blur.dart delete mode 100644 lib/input/sketch/entities/style/blur.g.dart delete mode 100644 lib/input/sketch/entities/style/border.dart delete mode 100644 lib/input/sketch/entities/style/border.g.dart delete mode 100644 lib/input/sketch/entities/style/border_options.dart delete mode 100644 lib/input/sketch/entities/style/border_options.g.dart delete mode 100644 lib/input/sketch/entities/style/color.dart delete mode 100644 lib/input/sketch/entities/style/color.g.dart delete mode 100644 lib/input/sketch/entities/style/color_controls.dart delete mode 100644 lib/input/sketch/entities/style/color_controls.g.dart delete mode 100644 lib/input/sketch/entities/style/context_settings.dart delete mode 100644 lib/input/sketch/entities/style/context_settings.g.dart delete mode 100644 lib/input/sketch/entities/style/fill.dart delete mode 100644 lib/input/sketch/entities/style/fill.g.dart delete mode 100644 lib/input/sketch/entities/style/font_descriptor.dart delete mode 100644 lib/input/sketch/entities/style/font_descriptor.g.dart delete mode 100644 lib/input/sketch/entities/style/gradient.dart delete mode 100644 lib/input/sketch/entities/style/gradient.g.dart delete mode 100644 lib/input/sketch/entities/style/gradient_stop.dart delete mode 100644 lib/input/sketch/entities/style/gradient_stop.g.dart delete mode 100644 lib/input/sketch/entities/style/paragraph_style.dart delete mode 100644 lib/input/sketch/entities/style/paragraph_style.g.dart delete mode 100644 lib/input/sketch/entities/style/shared_style.dart delete mode 100644 lib/input/sketch/entities/style/shared_style.g.dart delete mode 100644 lib/input/sketch/entities/style/style.dart delete mode 100644 lib/input/sketch/entities/style/style.g.dart delete mode 100644 lib/input/sketch/entities/style/text_style.dart delete mode 100644 lib/input/sketch/entities/style/text_style.g.dart delete mode 100644 lib/input/sketch/helper/sketch_asset_processor.dart delete mode 100644 lib/input/sketch/helper/sketch_page.dart delete mode 100644 lib/input/sketch/helper/sketch_project.dart delete mode 100644 lib/input/sketch/helper/sketch_screen.dart delete mode 100644 lib/input/sketch/helper/symbol_node_mixin.dart delete mode 100644 lib/input/sketch/services/input_design.dart delete mode 100644 lib/input/sketch/services/positional_cleansing_service.dart create mode 100644 lib/interpret_and_optimize/entities/alignments/injected_align.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_bitmap.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_circle.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_container.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_oval.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_polygon.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_scaffold.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_shape_group.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_shape_path.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_star.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_text.g.dart create mode 100644 lib/interpret_and_optimize/entities/inherited_triangle.g.dart create mode 100644 lib/interpret_and_optimize/entities/injected_container.g.dart create mode 100644 lib/interpret_and_optimize/entities/intermediate_border_info.dart create mode 100644 lib/interpret_and_optimize/entities/intermediate_border_info.g.dart create mode 100644 lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart create mode 100644 lib/interpret_and_optimize/entities/pb_shared_instance.g.dart create mode 100644 lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart create mode 100644 lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart create mode 100644 lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart create mode 100644 lib/interpret_and_optimize/helpers/index_walker.dart create mode 100644 lib/interpret_and_optimize/helpers/override_helper.dart create mode 100644 lib/interpret_and_optimize/helpers/pb_color.dart create mode 100644 lib/interpret_and_optimize/helpers/pb_color.g.dart create mode 100644 lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart create mode 100644 lib/interpret_and_optimize/helpers/pb_project.g.dart create mode 100644 lib/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart create mode 100644 lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart create mode 100644 lib/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart create mode 100644 lib/interpret_and_optimize/state_management/intermediate_auxillary_data.g.dart create mode 160000 pbdl diff --git a/.gitmodules b/.gitmodules index 91961aa6..e584bd51 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ -[submodule "SketchAssetConverter"] - path = SketchAssetConverter - url = https://github.com/Parabeac/SketchAssetConverter.git - branch = master +[submodule "pbdl"] + path = pbdl + url = https://github.com/Parabeac/pbdl diff --git a/SketchAssetConverter b/SketchAssetConverter deleted file mode 160000 index 1b5effbd..00000000 --- a/SketchAssetConverter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1b5effbd220ff03015bc4b288184005e4443f056 diff --git a/lib/controllers/design_controller.dart b/lib/controllers/design_controller.dart deleted file mode 100644 index 071ddc30..00000000 --- a/lib/controllers/design_controller.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/input/helper/asset_processing_service.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/helper/design_project.dart'; - -import 'controller.dart'; - -class DesignController extends Controller { - @override - DesignType get designType => DesignType.PBDL; - - @override - void convertFile({ - DesignProject designProject, - AssetProcessingService apService, - }) async { - var pbdf = MainInfo().pbdf; - if (pbdf == null) { - throw Error(); //todo: throw correct error - } - designProject ??= generateDesignProject(pbdf, MainInfo().genProjectPath); - AzureAssetService().projectUUID = pbdf['id']; - - super.convert(designProject, apService); - } - - DesignProject generateDesignProject(var pbdf, var proejctName) { - return DesignProject.fromPBDF(pbdf); - } -} diff --git a/lib/controllers/figma_controller.dart b/lib/controllers/figma_controller.dart deleted file mode 100644 index 7af33949..00000000 --- a/lib/controllers/figma_controller.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:parabeac_core/controllers/controller.dart'; -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/input/figma/entities/layers/component.dart'; -import 'package:parabeac_core/input/figma/entities/layers/frame.dart'; -import 'package:parabeac_core/input/figma/helper/api_call_service.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; -import 'package:parabeac_core/input/figma/helper/figma_project.dart'; -import 'package:parabeac_core/input/helper/asset_processing_service.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/helper/design_project.dart'; - -class FigmaController extends Controller { - @override - DesignType get designType => DesignType.FIGMA; - - @override - void convertFile({ - DesignProject designProject, - AssetProcessingService apService, - }) async { - var jsonFigma = await _fetchFigmaFile(); - if (jsonFigma == null) { - throw Error(); //todo: find correct error - } - AzureAssetService().projectUUID = MainInfo().figmaProjectID; - designProject ??= generateFigmaTree(jsonFigma, MainInfo().genProjectPath); - designProject = declareScaffolds(designProject); - - _sortPages(designProject); - super.convert(designProject, apService ?? FigmaAssetProcessor()); - } - - FigmaProject generateFigmaTree(var jsonFigma, var projectname) { - try { - return FigmaProject( - projectname, - jsonFigma, - id: MainInfo().figmaProjectID, - ); - } catch (e, stackTrace) { - print(e); - return null; - } - } - - Future _fetchFigmaFile() => APICallService.makeAPICall( - 'https://api.figma.com/v1/files/${MainInfo().figmaProjectID}', - MainInfo().figmaKey); - - /// This method was required for Figma, so we could - /// detect which `FigmaFrame` were Scaffolds or Containers - FigmaProject declareScaffolds(FigmaProject tree) { - for (var page in tree.pages) { - for (var item in page.getPageItems()) { - if (item.designNode is FigmaFrame) { - (item.designNode as FigmaFrame).isScaffold = true; - } - } - } - return tree; - } - - /// Sorts project's pages so that Components are processed last - void _sortPages(FigmaProject project) { - // Sort pages so that pages containing components are last - project.pages.sort((a, b) { - if (a.screens.any((screen) => screen.designNode is Component)) { - return 1; - } else if (b.screens.any((screen) => screen.designNode is Component)) { - return -1; - } - return 0; - }); - - // Within each page, ensure screens that are components go last - project.pages.forEach((page) { - page.screens.sort((a, b) { - if (a.designNode is Component) { - return 1; - } else if (b.designNode is Component) { - return -1; - } - return 0; - }); - }); - } - - @override - Future setup() async { - var processInfo = MainInfo(); - if (processInfo.figmaKey == null || processInfo.figmaProjectID == null) { - throw Error(); //todo: place correct error - } - } -} diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 7483db2e..9e379bc9 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -1,12 +1,16 @@ import 'dart:io'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; -import 'package:parabeac_core/input/helper/design_project.dart'; -import 'package:parabeac_core/input/helper/design_page.dart'; -import 'package:parabeac_core/input/helper/design_screen.dart'; +import 'dart:convert'; + +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/prototyping/pb_prototype_aggregation_service.dart'; +import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -18,9 +22,10 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generati import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_visual_generation_service.dart'; +import 'package:pbdl/pbdl.dart'; import 'package:quick_log/quick_log.dart'; import 'package:tuple/tuple.dart'; +import 'package:path/path.dart' as p; class Interpret { var log = Logger('Interpret'); @@ -29,70 +34,38 @@ class Interpret { static final Interpret _interpret = Interpret._internal(); - factory Interpret() { + factory Interpret({PBConfiguration configuration}) { + _interpret.configuration ??= configuration; + _interpret._pbPrototypeLinkerService ??= PBPrototypeLinkerService(); return _interpret; } - PBProject _pb_project; - PBSymbolLinkerService _pbSymbolLinkerService; + PBProject _pbProject; PBPrototypeLinkerService _pbPrototypeLinkerService; PBConfiguration configuration; void init(String projectName, PBConfiguration configuration) { this.configuration ??= configuration; log = Logger(runtimeType.toString()); - _interpret._pbSymbolLinkerService = PBSymbolLinkerService(); - _interpret._pbPrototypeLinkerService = PBPrototypeLinkerService(); + // _interpret._pbSymbolLinkerService = PBSymbolLinkerService(); + // _interpret._pbPrototypeLinkerService = PBPrototypeLinkerService(); } - Future interpretAndOptimize( - DesignProject tree, String projectName, String projectPath) async { - _pb_project = PBProject(projectName, projectPath, tree.sharedStyles); - - ///3rd Party Symbols - if (tree.miscPages != null) { - for (var i = 0; i < tree.miscPages?.length; i++) { - _pb_project.forest - .addAll((await _generateIntermediateTree(tree.miscPages[i]))); - } - } - - /// Main Pages - if (tree.pages != null) { - for (var i = 0; i < tree.pages?.length; i++) { - _pb_project.forest - .addAll((await _generateIntermediateTree(tree.pages[i]))); - } - } + Future interpretAndOptimize(PBDLProject project) async { + _pbProject = PBProject.fromJson(project.toJson()); - return _pb_project; - } + _pbProject.projectAbsPath = + p.join(MainInfo().outputPath, MainInfo().projectName); - /// Taking a design page, returns a PBIntermediateTree verison of it - Future> _generateIntermediateTree( - DesignPage designPage) async { - var tempForest = []; - var pageItems = designPage.getPageItems(); - for (var i = 0; i < pageItems.length; i++) { - var tree = await _generateScreen(pageItems[i]); - if (tree != null && tree.rootNode != null) { - tree.name = designPage.name; - - tree.data = PBGenerationViewData(); - if (tree.isScreen()) { - PBPlatformOrientationLinkerService() - .addOrientationPlatformInformation(tree); - } + _pbProject.forest = await Future.wait(_pbProject.forest + .map((tree) async => await _generateScreen(tree)) + .toList()); + _pbProject.forest.removeWhere((element) => element == null); - if (tree != null) { - log.fine( - 'Processed \'${tree.name}\' in group \'${designPage.name}\' with item type: \'${tree.tree_type}\''); + // TODO: do this in just one go + await PBPrototypeAggregationService().linkDanglingPrototypeNodes(); - tempForest.add(tree); - } - } - } - return tempForest; + return _pbProject; } Future _generateScreen(DesignScreen designScreen) async { diff --git a/lib/controllers/main_info.dart b/lib/controllers/main_info.dart index 770010b1..4d15ea01 100644 --- a/lib/controllers/main_info.dart +++ b/lib/controllers/main_info.dart @@ -1,25 +1,23 @@ import 'dart:io'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; -import 'package:sentry/sentry.dart'; import 'package:path/path.dart' as p; class MainInfo { static final MainInfo _singleton = MainInfo._internal(); - - final SentryClient _sentry = SentryClient( - dsn: - 'https://6e011ce0d8cd4b7fb0ff284a23c5cb37@o433482.ingest.sentry.io/5388747'); - @Deprecated('Use the function handle error for logging and capturing the error') - SentryClient get sentry => _sentry; + final _sentry = DummySentry(); + + @Deprecated( + 'Use the function handle error for logging and capturing the error') + get sentry => _sentry; /// Path representing where the output of parabeac-core will be produced to. - /// - /// First, we are going to check the if any path was passed as a flag to [outputPath], + /// + /// First, we are going to check the if any path was passed as a flag to [outputPath], /// then check in the [configuration] to see if there are any paths saved ([PBConfiguration.outputDirPath]). String _outputPath; - String get outputPath => _outputPath ?? configuration?.outputDirPath; + String get outputPath => _outputPath ?? configuration?.outputDirPath; set outputPath(String path) => _outputPath = _validatePath(path); /// Path to the user's sketch file @@ -28,9 +26,9 @@ class MainInfo { set designFilePath(String path) => _designFilePath = _validatePath(path); /// Absolute path of where the flutter project is going to be generating at. - /// - /// If its PBC is generating the flutter project, its going to [p.join] the - /// [outputPath] and the [projectName]. Meaning the the code should be generated + /// + /// If its PBC is generating the flutter project, its going to [p.join] the + /// [outputPath] and the [projectName]. Meaning the the code should be generated /// into the flutter directory. Otherwise, the code is going to be generated within the directory /// specified in the [outputPath]. String get genProjectPath { @@ -103,7 +101,7 @@ class MainInfo { /// Decoupling the exception capture client from the services that report the [exception] void captureException(exception) { - _sentry.captureException(exception: exception); + // _sentry.captureException(exception: exception); } factory MainInfo() { @@ -115,3 +113,10 @@ class MainInfo { /// The type of design that is being processed by Parabeac Core. enum DesignType { SKETCH, FIGMA, PBDL, UNKNOWN } + +class DummySentry { + /// Decoupling the exception capture client from the services that report the [exception] + void captureException({exception, stackTrace}) { + print('dummy sentry'); + } +} diff --git a/lib/controllers/sketch_controller.dart b/lib/controllers/sketch_controller.dart deleted file mode 100644 index 7b2a8832..00000000 --- a/lib/controllers/sketch_controller.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'dart:io'; -import 'dart:convert'; - -import 'package:parabeac_core/controllers/controller.dart'; -import 'package:parabeac_core/input/helper/asset_processing_service.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; - -import 'package:parabeac_core/input/helper/design_project.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_project.dart'; -import 'package:parabeac_core/input/sketch/services/input_design.dart'; - -import 'main_info.dart'; -import 'package:path/path.dart' as p; - -class SketchController extends Controller { - @override - DesignType get designType => DesignType.SKETCH; - - ///Converting the [fileAbsPath] sketch file to flutter - @override - void convertFile({ - DesignProject designProject, - AssetProcessingService apService, - }) async { - var processInfo = MainInfo(); - - ///INTAKE - var ids = InputDesignService(processInfo.designFilePath, - jsonOnly: processInfo.exportPBDL); - designProject ??= generateSketchNodeTree( - ids, ids.metaFileJson['pagesAndArtboards'], processInfo.genProjectPath); - - AzureAssetService().projectUUID = designProject.id; - - super.convert(designProject, apService ?? SketchAssetProcessor()); - } - - SketchProject generateSketchNodeTree( - InputDesignService ids, Map pagesAndArtboards, projectName) { - try { - return SketchProject(ids, pagesAndArtboards, projectName); - } catch (e, stackTrace) { - MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); - log.error(e.toString()); - return null; - } - } - - @override - Future setup() async { - var processInfo = MainInfo(); - if (!processInfo.exportPBDL) { - if (!FileSystemEntity.isFileSync(processInfo.designFilePath)) { - throw Error(); - } - InputDesignService(processInfo.designFilePath); - await checkSACVersion(); - } - await super.setup(); - } - - Future checkSACVersion() async { - /// Code is moved from `main.dart` - Process process; - if (!Platform.environment.containsKey('SAC_ENDPOINT')) { - var isSACupToDate = await Process.run( - './pb-scripts/check-git.sh', - [], - workingDirectory: MainInfo().cwd.path, - ); - - if (isSACupToDate.stdout - .contains('Sketch Asset Converter is behind master.')) { - log.warning(isSACupToDate.stdout); - } else { - log.info(isSACupToDate.stdout); - } - - process = await Process.start('npm', ['run', 'prod'], - workingDirectory: - p.join(MainInfo().cwd.path, 'SketchAssetConverter')); - - await for (var event in process.stdout.transform(utf8.decoder)) { - if (event.toLowerCase().contains('server is listening on port')) { - log.fine('Successfully started Sketch Asset Converter'); - break; - } - } - process?.kill(); - } - } -} diff --git a/lib/design_logic/abstract_design_node_factory.dart b/lib/design_logic/abstract_design_node_factory.dart deleted file mode 100644 index ce0ac314..00000000 --- a/lib/design_logic/abstract_design_node_factory.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:parabeac_core/input/helper/design_page.dart'; -import 'package:parabeac_core/input/helper/design_project.dart'; -import 'package:parabeac_core/input/helper/design_screen.dart'; - -import 'artboard.dart'; -import 'boolean_operation.dart'; -import 'design_node.dart'; -import 'group_node.dart'; -import 'image.dart'; -import 'oval.dart'; -import 'pb_shared_instance_design_node.dart'; -import 'pb_shared_master_node.dart'; -import 'polygon.dart'; -import 'rectangle.dart'; -import 'star.dart'; -import 'text.dart'; -import 'vector.dart'; - -class AbstractDesignNodeFactory { - static final String DESIGN_CLASS_KEY = 'pbdfType'; - - static final List _designNodes = [ - PBArtboard(), - BooleanOperation(), - GroupNode(), - Image(), - Oval(), - PBSharedInstanceDesignNode(), - PBSharedMasterDesignNode(), - Polygon(), - Rectangle(), - Star(), - Text(), - Vector(), - DesignProject(), - DesignPage(), - DesignScreen(), - ]; - - AbstractDesignNodeFactory(); - - static DesignNode getDesignNode(Map json) { - var className = json[DESIGN_CLASS_KEY]; - if (className != null) { - for (var designNode in _designNodes) { - if (designNode.pbdfType == className) { - return designNode.createDesignNode(json); - } - } - } - return null; - } -} - -abstract class DesignNodeFactory { - String pbdfType; - DesignNode createDesignNode(Map json); -} diff --git a/lib/design_logic/artboard.dart b/lib/design_logic/artboard.dart deleted file mode 100644 index 075e5c58..00000000 --- a/lib/design_logic/artboard.dart +++ /dev/null @@ -1,129 +0,0 @@ -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/group_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/design_logic/rect.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -import 'abstract_design_node_factory.dart'; - -class PBArtboard extends DesignNode implements GroupNode, DesignNodeFactory { - PBColor backgroundColor; - @override - var boundaryRectangle; - var isFlowHome; - - @override - var style; - PBArtboard( - {Color this.backgroundColor, - this.isFlowHome, - hasClickThrough, - groupLayout, - UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - maintainScrollPosition, - prototypeNode, - type, - this.style}) - : super(UUID, name, isVisible, boundaryRectangle, type, style, - prototypeNode); - - @override - List children = []; - - @override - String pbdfType = 'artboard'; - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - @override - DesignNode fromPBDF(Map json) { - var node = PBArtboard( - backgroundColor: json['backgroundColor'] == null - ? null - : Color.fromJson(json['backgroundColor'] as Map), - isFlowHome: json['isFlowHome'] as bool, - hasClickThrough: json['hasClickThrough'], - groupLayout: json['groupLayout'], - UUID: json['id'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['visible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - maintainScrollPosition: json['maintainScrollPosition'], - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..type = json['type'] as String; - if (json.containsKey('children')) { - if (json['children'] != null) { - for (var item in json['children']) { - var child = DesignNode.fromPBDF(item as Map); - if (child != null) { - node.children.add(child); - } - } - } - } - return node; - } - - @override - Future interpretNode(PBContext currentContext) { - return Future.value(InheritedScaffold( - this, - currentContext: currentContext, - name: name, - isHomeScreen: isFlowHome, - )); - } -} diff --git a/lib/design_logic/boolean_operation.dart b/lib/design_logic/boolean_operation.dart deleted file mode 100644 index d17b6fdf..00000000 --- a/lib/design_logic/boolean_operation.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:io'; -import 'package:path/path.dart' as p; - -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - -import 'abstract_design_node_factory.dart'; - -class BooleanOperation implements DesignNodeFactory, DesignNode { - @override - String pbdfType = 'boolean_operation'; - List children = []; - - @override - var boundaryRectangle; - - BooleanOperation({ - booleanOperation, - type, - Frame this.boundaryRectangle, - String UUID, - this.name, - bool isVisible, - pbdfType, - }); - - @override - Future interpretNode(PBContext currentContext) async { - var img = await AzureAssetService().downloadImage(UUID); - var path = - p.join(MainInfo().pngPath, '$UUID.png'.replaceAll(':', '_')); - var file = File(path)..createSync(recursive: true); - file.writeAsBytesSync(img); - - return Future.value(InheritedBitmap( - this, - name, - currentContext: currentContext, - )); - } - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - DesignNode fromPBDF(Map json) { - var node = BooleanOperation( - booleanOperation: json['booleanOperation'], - type: json['type'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - UUID: json['id'] as String, - name: json['name'] as String, - isVisible: json['visible'] as bool ?? true, - pbdfType: json['pbdfType'] as String, - ); - if (json.containsKey('children')) { - if (json['children'] != null) { - node.children - .add(DesignNode.fromPBDF(json['children'] as Map)); - } - } - return node; - } - - @override - String UUID; - - @override - String name; - - @override - String prototypeNodeUUID; - - @override - PBStyle style; - - @override - String type; - - @override - toJson() { - throw UnimplementedError(); - } - - @override - Map toPBDF() { - throw UnimplementedError(); - } - - @override - bool isVisible; -} diff --git a/lib/design_logic/color.dart b/lib/design_logic/color.dart deleted file mode 100644 index 4007bb4c..00000000 --- a/lib/design_logic/color.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:hex/hex.dart'; - -abstract class PBColor { - PBColor( - this.alpha, - this.red, - this.green, - this.blue, - ); - - double alpha; - double red; - double green; - double blue; - - toJson(); -} - -mixin PBColorMixin { - String toHex(PBColor color) { - if (color != null) { - int a, r, g, b; - a = ((color.alpha ?? 0) * 255).round(); - r = ((color.red ?? 0) * 255).round(); - g = ((color.green ?? 0) * 255).round(); - b = ((color.blue ?? 0) * 255).round(); - return '0x' + HEX.encode([a, r, g, b]); - } else { - return '0x' + HEX.encode([0, 0, 0, 0]); - } - } - - String findDefaultColor(String hex) { - switch (hex) { - case '0xffffffff': - return 'Colors.white'; - break; - case '0xff000000': - return 'Colors.black'; - break; - } - return null; - } - -} diff --git a/lib/design_logic/design_element.dart b/lib/design_logic/design_element.dart deleted file mode 100644 index 7212e6b9..00000000 --- a/lib/design_logic/design_element.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; - -abstract class DesignElement extends DesignNode { - DesignElement({ - UUID, - name, - isVisible, - boundaryRectangle, - type, - style, - prototypeNodeUUID, - }) : super( - UUID, - name, - isVisible, - boundaryRectangle, - type, - style, - prototypeNodeUUID, - ); -} diff --git a/lib/design_logic/design_node.dart b/lib/design_logic/design_node.dart deleted file mode 100644 index a7dcafff..00000000 --- a/lib/design_logic/design_node.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -import 'abstract_design_node_factory.dart'; - -class DesignNode { - DesignNode( - this.UUID, - this.name, - this.isVisible, - this.boundaryRectangle, - this.type, - this.style, - this.prototypeNodeUUID, - ); - - String pbdfType; - String UUID; - String name; - bool isVisible; - var boundaryRectangle; - String type; - PBStyle style; - String prototypeNodeUUID; - - toJson() {} - - Future interpretNode(PBContext currentContext) {} - - Map toPBDF() {} - - factory DesignNode.fromPBDF(Map json) => - AbstractDesignNodeFactory.getDesignNode(json); - - factory DesignNode.fromJson(Map json) => - AbstractDesignNodeFactory.getDesignNode(json); -} diff --git a/lib/design_logic/design_shape.dart b/lib/design_logic/design_shape.dart deleted file mode 100644 index d19b344e..00000000 --- a/lib/design_logic/design_shape.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:parabeac_core/design_logic/design_element.dart'; - -abstract class DesignShape extends DesignElement { - DesignShape() : super(); -} diff --git a/lib/design_logic/group_node.dart b/lib/design_logic/group_node.dart deleted file mode 100644 index cabda6d5..00000000 --- a/lib/design_logic/group_node.dart +++ /dev/null @@ -1,139 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'dart:math'; - -import 'abstract_design_node_factory.dart'; - -class GroupNode implements DesignNodeFactory, DesignNode { - List children = []; - - @override - String pbdfType = 'group'; - - GroupNode({ - bool hasClickThrough, - groupLayout, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - this.isVisible, - layerListExpandedType, - this.name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - maintainScrollPosition, - this.pbdfType = 'group', - this.style, - }); - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - DesignNode fromPBDF(Map json) { - var node = GroupNode( - hasClickThrough: json['hasClickThrough'] as bool, - groupLayout: json['groupLayout'], - UUID: json['id'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['visible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - maintainScrollPosition: json['maintainScrollPosition'], - pbdfType: json['pbdfType'], - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..type = json['type'] as String; - if (json.containsKey('children')) { - if (json['children'] != null) { - for (var item in json['children']) { - var child = DesignNode.fromPBDF(item as Map); - if (child != null) { - node.children.add(child); - } - } - } - } - return node; - } - - @override - String UUID; - - @override - var boundaryRectangle; - - @override - bool isVisible; - - @override - String name; - - @override - String prototypeNodeUUID; - - @override - PBStyle style; - - @override - String type; - - @override - Future interpretNode(PBContext currentContext) => - Future.value(TempGroupLayoutNode( - this, - currentContext, - name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point( - boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - )); - - @override - toJson() { - // TODO: implement toJson - throw UnimplementedError(); - } - - @override - Map toPBDF() { - // TODO: implement toPBDF - throw UnimplementedError(); - } -} diff --git a/lib/design_logic/image.dart b/lib/design_logic/image.dart deleted file mode 100644 index a7fc0bbe..00000000 --- a/lib/design_logic/image.dart +++ /dev/null @@ -1,121 +0,0 @@ -import 'dart:io'; -import 'package:path/path.dart' as p; - -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_element.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -import 'abstract_design_node_factory.dart'; - -class Image extends DesignElement implements DesignNodeFactory, DesignNode { - @override - var style; - - Image({ - this.imageReference, - UUID, - booleanOperation, - exportOptions, - Frame boundaryRectangle, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - num rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - maintainScrollPosition, - this.pbdfType = 'image', - this.style, - }) : super( - UUID: UUID, - name: name, - isVisible: isVisible, - boundaryRectangle: boundaryRectangle, - style: style, - ); - - String imageReference; - - @override - String pbdfType = 'image'; - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - DesignNode fromPBDF(Map json) { - return Image( - UUID: json['id'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['visible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'] as num, - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - maintainScrollPosition: json['maintainScrollPosition'], - pbdfType: json['pbdfType'], - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..type = json['type'] as String; - } - - @override - Future interpretNode(PBContext currentContext) async { - var pngsPath = - p.join(MainInfo().pngPath, '$UUID.png'.replaceAll(':', '_')); - try { - var img = await AzureAssetService().downloadImage(UUID); - var file = File(pngsPath)..createSync(recursive: true); - file.writeAsBytesSync(img); - return Future.value(InheritedBitmap( - this, - name, - currentContext: currentContext, - )); - } catch (e) { - var errPath = p.join(MainInfo().cwd?.path, 'lib', 'input', 'assets', - 'image-conversion-error.png'); - var img = File(errPath).readAsBytesSync(); - var file = File(pngsPath)..createSync(recursive: true); - file.writeAsBytesSync(img); - return Future.value(InheritedBitmap( - this, - name, - currentContext: currentContext, - )); - } - } -} diff --git a/lib/design_logic/oval.dart b/lib/design_logic/oval.dart deleted file mode 100644 index a85e6fc1..00000000 --- a/lib/design_logic/oval.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_oval.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - -import 'abstract_design_node_factory.dart'; - -class Oval implements DesignNodeFactory, DesignNode { - @override - String pbdfType = 'oval'; - - @override - var boundaryRectangle; - - @override - var UUID; - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - Oval({ - bool edited, - bool isClosed, - pointRadiusBehaviour, - List points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - this.isVisible, - layerListExpandedType, - this.name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - maintainScrollPosition, - type, - this.pbdfType = 'oval', - this.style, - }); - DesignNode fromPBDF(Map json) { - return Oval( - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['id'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['visible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - maintainScrollPosition: json['maintainScrollPosition'], - type: json['type'] as String, - pbdfType: json['pbdfType'] as String, - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - ); - } - - @override - bool isVisible; - - @override - String name; - - @override - String prototypeNodeUUID; - - @override - PBStyle style; - - @override - String type; - - @override - Future interpretNode(PBContext currentContext) async { - var img = await AzureAssetService().downloadImage(UUID); - - return Future.value( - InheritedOval(this, name, currentContext: currentContext, image: img)); - } - - @override - toJson() { - throw UnimplementedError(); - } - - @override - Map toPBDF() { - throw UnimplementedError(); - } -} diff --git a/lib/design_logic/pb_border.dart b/lib/design_logic/pb_border.dart deleted file mode 100644 index 6d701e06..00000000 --- a/lib/design_logic/pb_border.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'color.dart'; - -abstract class PBBorder { - final bool isEnabled; - final double fillType; - final PBColor color; - final double thickness; - - PBBorder({ - this.isEnabled = true, - this.fillType, - this.color, - this.thickness, - }); - - toJson(); -} diff --git a/lib/design_logic/pb_border_options.dart b/lib/design_logic/pb_border_options.dart deleted file mode 100644 index e3f383fa..00000000 --- a/lib/design_logic/pb_border_options.dart +++ /dev/null @@ -1,14 +0,0 @@ -abstract class PBBorderOptions { - bool isEnabled; - List dashPattern; - int lineCapStyle, lineJoinStyle; - - PBBorderOptions({ - this.isEnabled, - this.dashPattern, - this.lineCapStyle, - this.lineJoinStyle, - }); - - toJson(); -} diff --git a/lib/design_logic/pb_fill.dart b/lib/design_logic/pb_fill.dart deleted file mode 100644 index 35113753..00000000 --- a/lib/design_logic/pb_fill.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:parabeac_core/design_logic/color.dart'; - -abstract class PBFill { - PBColor color; - bool isEnabled; - int fillType; - - PBFill(this.color, this.fillType, [this.isEnabled = true]); - - toJson(); -} diff --git a/lib/design_logic/pb_font_descriptor.dart b/lib/design_logic/pb_font_descriptor.dart deleted file mode 100644 index a0d5bb55..00000000 --- a/lib/design_logic/pb_font_descriptor.dart +++ /dev/null @@ -1,5 +0,0 @@ -abstract class PBFontDescriptor { - Map rawAttributes; - String fontName; - num fontSize; -} diff --git a/lib/design_logic/pb_paragraph_style.dart b/lib/design_logic/pb_paragraph_style.dart deleted file mode 100644 index e57b6243..00000000 --- a/lib/design_logic/pb_paragraph_style.dart +++ /dev/null @@ -1,10 +0,0 @@ -abstract class PBParagraphStyle { - int alignment; -} - -enum ALIGNMENT { - LEFT, - RIGHT, - CENTER, - JUSTIFY, -} diff --git a/lib/design_logic/pb_shared_instance_design_node.dart b/lib/design_logic/pb_shared_instance_design_node.dart deleted file mode 100644 index 3494b21a..00000000 --- a/lib/design_logic/pb_shared_instance_design_node.dart +++ /dev/null @@ -1,132 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/override_value.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -import 'abstract_design_node_factory.dart'; - -class PBSharedInstanceDesignNode extends DesignNode - with SymbolNodeMixin - implements DesignNodeFactory { - String symbolID; - List parameters; - - PBSharedInstanceDesignNode( - {String UUID, - this.overrideValues, - String name, - bool isVisible, - boundaryRectangle, - String type, - style, - prototypeNode, - exportOptions, - booleanOperation, - bool isFixedToViewport, - bool isFlippedVertical, - bool isFlippedHorizontal, - bool isLocked, - layerListExpandedType, - bool nameIsFixed, - resizingConstraint, - resizingType, - num rotation, - sharedStyleID, - bool shouldBreakMaskChain, - bool hasClippingMask, - int clippingMaskMode, - userInfo, - bool maintainScrollPosition, - num scale, - this.symbolID, - num verticalSpacing, - num horizontalSpacing, - this.pbdfType}) - : super(UUID, name, isVisible, boundaryRectangle, type, style, - prototypeNode) { - pbdfType = 'symbol_instance'; - } - - @override - String pbdfType = 'symbol_instance'; - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - DesignNode fromPBDF(Map json) { - return PBSharedInstanceDesignNode( - UUID: json['id'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - isFixedToViewport: json['isFixedToViewport'] as bool, - isFlippedHorizontal: json['isFlippedHorizontal'] as bool, - isFlippedVertical: json['isFlippedVertical'] as bool, - isLocked: json['isLocked'] as bool, - isVisible: json['visible'] as bool, - layerListExpandedType: json['layerListExpandedType'], - name: json['name'] as String, - nameIsFixed: json['nameIsFixed'] as bool, - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'] as num, - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'] as bool, - hasClippingMask: json['hasClippingMask'] as bool, - clippingMaskMode: json['clippingMaskMode'] as int, - userInfo: json['userInfo'], - maintainScrollPosition: json['maintainScrollPosition'] as bool, - overrideValues: (json['overrideValues'] as List) - ?.map((e) => e == null - ? null - : OverridableValue.fromJson(e as Map)) - ?.toList(), - scale: (json['scale'] as num)?.toDouble(), - symbolID: json['symbolID'] as String, - verticalSpacing: (json['verticalSpacing'] as num)?.toDouble(), - horizontalSpacing: (json['horizontalSpacing'] as num)?.toDouble(), - type: json['type'] as String, - pbdfType: json['pbdfType'], - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..parameters = json['parameters'] as List; - } - - @override - Future interpretNode(PBContext currentContext) { - var sym = PBSharedInstanceIntermediateNode(this, symbolID, - sharedParamValues: _extractParameters(), - currentContext: currentContext); - return Future.value(sym); - } - - ///Converting the [OverridableValue] into [PBSharedParameterValue] to be processed in intermediate phase. - List _extractParameters() { - var ovrNames = {}; - var sharedParameters = []; - for (var overrideValue in overrideValues) { - if (!ovrNames.contains(overrideValue.overrideName)) { - var properties = extractParameter(overrideValue.overrideName); - sharedParameters.add(PBSharedParameterValue( - properties['type'], - overrideValue.value, - properties['uuid'], - overrideValue.overrideName)); - ovrNames.add(overrideValue.overrideName); - } - } - - return sharedParameters; - } - - final List overrideValues; -} diff --git a/lib/design_logic/pb_shared_master_node.dart b/lib/design_logic/pb_shared_master_node.dart deleted file mode 100644 index 98c32c74..00000000 --- a/lib/design_logic/pb_shared_master_node.dart +++ /dev/null @@ -1,181 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/group_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/override_property.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; - -import 'abstract_design_node_factory.dart'; - -class PBSharedMasterDesignNode extends DesignNode - with SymbolNodeMixin - implements DesignNodeFactory, GroupNode { - String symbolID; - List overriadableProperties; - - var overrideProperties; - - PBSharedMasterDesignNode({ - String UUID, - this.overrideProperties, - String name, - bool isVisible, - boundaryRectangle, - String type, - style, - prototypeNode, - bool hasClickThrough, - groupLayout, - booleanOperation, - exportOptions, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - layerListExpandedType, - this.pbdfType, - presetDictionary, - bool allowsOverrides, - nameIsFixed, - resizingConstraint, - resizingType, - horizontalRulerData, - bool hasBackgroundColor, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - maintainScrollPosition, - bool includeBackgroundColorInExport, - int changeIdentifier, - this.symbolID, - bool includeBackgroundColorInInstance, - verticalRulerData, - bool resizesContent, - bool includeInCloudUpload, - bool isFlowHome, - List parameters, - }) : super(UUID, name, isVisible, boundaryRectangle, type, style, - prototypeNode) { - pbdfType = 'symbol_master'; - } - - @override - String pbdfType = 'symbol_master'; - - @override - Future interpretNode(PBContext currentContext) { - var sym_master = PBSharedMasterNode( - this, - symbolID, - name, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - overridableProperties: _extractParameters(), - currentContext: currentContext, - ); - return Future.value(sym_master); - } - - ///Converting the [OverridableProperty] into [PBSharedParameterProp] to be processed in intermediate phase. - List _extractParameters() { - var ovrNames = {}; - var sharedParameters = []; - for (var prop in overrideProperties) { - if (!ovrNames.contains(prop.overrideName)) { - var properties = AddMasterSymbolOverrideName(prop.overrideName, children); - sharedParameters.add(PBSharedParameterProp( - properties['name'], - properties['type'], - null, - prop.canOverride, - prop.overrideName, - properties['uuid'], - properties['default_value'])); - ovrNames.add(prop.overrideName); - } - } - return sharedParameters; - } - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - @override - DesignNode fromPBDF(Map json) { - var node = PBSharedMasterDesignNode( - hasClickThrough: json['hasClickThrough'] as bool, - groupLayout: json['groupLayout'], - UUID: json['id'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['visible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - maintainScrollPosition: json['maintainScrollPosition'], - hasBackgroundColor: json['hasBackgroundColor'] as bool, - horizontalRulerData: json['horizontalRulerData'], - includeBackgroundColorInExport: - json['includeBackgroundColorInExport'] as bool, - includeInCloudUpload: json['includeInCloudUpload'] as bool, - isFlowHome: json['isFlowHome'] as bool, - resizesContent: json['resizesContent'] as bool, - verticalRulerData: json['verticalRulerData'], - includeBackgroundColorInInstance: - json['includeBackgroundColorInInstance'] as bool, - symbolID: json['symbolID'] as String, - changeIdentifier: json['changeIdentifier'] as int, - allowsOverrides: json['allowsOverrides'] as bool, - overrideProperties: (json['overrideProperties'] as List) - ?.map((e) => e == null - ? null - : OverridableProperty.fromJson(e as Map)) - ?.toList(), - presetDictionary: json['presetDictionary'], - type: json['type'] as String, - pbdfType: json['pbdfType'], - parameters: json['parameters'] as List, - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - )..prototypeNodeUUID = json['prototypeNodeUUID'] as String; - - if (json.containsKey('children')) { - if (json['children'] != null) { - for (var item in json['children']) { - var child = DesignNode.fromPBDF(item as Map); - if (child != null) { - node.children.add(child); - } - } - } - } - return node; - } - - @override - List children = []; -} diff --git a/lib/design_logic/pb_style.dart b/lib/design_logic/pb_style.dart deleted file mode 100644 index d5402f6e..00000000 --- a/lib/design_logic/pb_style.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/pb_fill.dart'; -import 'package:parabeac_core/design_logic/pb_text_style.dart'; -import 'package:parabeac_core/design_logic/pb_border.dart'; -import 'package:parabeac_core/design_logic/pb_border_options.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_style.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; - -class PBStyle { - PBColor backgroundColor; - List fills; - List borders; - PBBorderOptions borderOptions; - PBTextStyle textStyle; - bool hasShadow = false; - - PBStyle({this.fills, this.backgroundColor}); - - // toPBDF() {} - - factory PBStyle.fromPBDF(Map json) { - if (json.containsKey('_class')) { - return Style.fromJson(json); - } else { - return FigmaStyle.fromJson(json); - } - } - - toJson() {} -} diff --git a/lib/design_logic/pb_text_style.dart b/lib/design_logic/pb_text_style.dart deleted file mode 100644 index ca30daba..00000000 --- a/lib/design_logic/pb_text_style.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/pb_font_descriptor.dart'; -import 'package:parabeac_core/design_logic/pb_paragraph_style.dart'; - -abstract class PBTextStyle { - PBColor fontColor; - String weight; - PBFontDescriptor fontDescriptor; - PBParagraphStyle paragraphStyle; - - PBTextStyle({ - this.fontColor, - this.weight, - this.paragraphStyle, - }); - - toJson(); -} diff --git a/lib/design_logic/polygon.dart b/lib/design_logic/polygon.dart deleted file mode 100644 index a782649f..00000000 --- a/lib/design_logic/polygon.dart +++ /dev/null @@ -1,124 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_polygon.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - -import 'abstract_design_node_factory.dart'; - -class Polygon implements DesignNodeFactory, DesignNode { - @override - String pbdfType = 'polygon'; - - @override - var boundaryRectangle; - - @override - var UUID; - - Polygon({ - bool edited, - bool isClosed, - pointRadiusBehaviour, - List points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - maintainScrollPosition, - type, - pbdfType, - this.style, - }); - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - DesignNode fromPBDF(Map json) { - return Polygon( - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['id'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['visible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - maintainScrollPosition: json['maintainScrollPosition'], - type: json['type'] as String, - pbdfType: json['pbdfType'] as String, - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - ); - } - - @override - bool isVisible; - - @override - String name; - - @override - String prototypeNodeUUID; - - @override - PBStyle style; - - @override - String type; - - @override - Future interpretNode(PBContext currentContext) async { - var img = await AzureAssetService().downloadImage(UUID); - - return Future.value(InheritedPolygon(this, name, - currentContext: currentContext, image: img)); - } - - @override - toJson() { - throw UnimplementedError(); - } - - @override - Map toPBDF() { - throw UnimplementedError(); - } -} diff --git a/lib/design_logic/rect.dart b/lib/design_logic/rect.dart deleted file mode 100644 index 09e305e1..00000000 --- a/lib/design_logic/rect.dart +++ /dev/null @@ -1,13 +0,0 @@ -abstract class Rect { - Rect( - this.x, - this.y, - this.width, - this.height, - ); - - double x; - double y; - double width; - double height; -} diff --git a/lib/design_logic/rectangle.dart b/lib/design_logic/rectangle.dart deleted file mode 100644 index f9ebe2ca..00000000 --- a/lib/design_logic/rectangle.dart +++ /dev/null @@ -1,158 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/border.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'dart:math'; - -import 'abstract_design_node_factory.dart'; -import 'color.dart'; - -class Rectangle with PBColorMixin implements DesignNodeFactory, DesignNode { - @override - String pbdfType = 'rectangle'; - - var hasConvertedToNewRoundCorners; - - var fixedRadius; - - var needsConvertionToNewRoundCorners; - - var points; - - Rectangle({ - this.fixedRadius, - this.hasConvertedToNewRoundCorners, - this.needsConvertionToNewRoundCorners, - bool edited, - bool isClosed, - pointRadiusBehaviour, - List this.points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - this.isVisible, - layerListExpandedType, - this.name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - maintainScrollPosition, - this.type, - this.pbdfType = 'rectangle', - this.style, - }); - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - DesignNode fromPBDF(Map json) { - return Rectangle( - fixedRadius: (json['fixedRadius'] as num)?.toDouble(), - hasConvertedToNewRoundCorners: - json['hasConvertedToNewRoundCorners'] as bool, - needsConvertionToNewRoundCorners: - json['needsConvertionToNewRoundCorners'] as bool, - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - type: json['type'] as String, - maintainScrollPosition: json['maintainScrollPosition'], - pbdfType: json['pbdfType'], - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - ); - } - - @override - String UUID; - - @override - var boundaryRectangle; - - @override - bool isVisible; - - @override - String name; - - @override - String prototypeNodeUUID; - - @override - PBStyle style; - - @override - String type; - - @override - Future interpretNode(PBContext currentContext) { - Border border; - for (var b in style.borders.reversed) { - if (b.isEnabled) { - border = b; - } - } - return Future.value(InheritedContainer( - this, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - name, - currentContext: currentContext, - borderInfo: { - 'borderRadius': - style.borderOptions.isEnabled ? points[0]['cornerRadius'] : null, - 'borderColorHex': border != null ? toHex(border.color) : null, - 'borderThickness': border != null ? border.thickness : null - }, - )); - } - - @override - toJson() { - throw UnimplementedError(); - } - - @override - Map toPBDF() { - throw UnimplementedError(); - } -} diff --git a/lib/design_logic/star.dart b/lib/design_logic/star.dart deleted file mode 100644 index 88e2bdb4..00000000 --- a/lib/design_logic/star.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_star.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; - -import 'abstract_design_node_factory.dart'; - -class Star implements DesignNodeFactory, DesignNode { - @override - String pbdfType = 'star'; - - Star({ - bool edited, - bool isClosed, - pointRadiusBehaviour, - List points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - maintainScrollPosition, - type, - pbdfType, - this.style, - }); - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - DesignNode fromPBDF(Map json) { - return Star( - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['visible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - maintainScrollPosition: json['maintainScrollPosition'], - type: json['_class'] as String, - pbdfType: json['pbdfType'], - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - ); - } - - @override - String UUID; - - @override - var boundaryRectangle; - - @override - bool isVisible; - - @override - String name; - - @override - String prototypeNodeUUID; - - @override - PBStyle style; - - @override - String type; - - @override - Future interpretNode(PBContext currentContext) async { - var img = await AzureAssetService().downloadImage(UUID); - return Future.value( - InheritedStar(this, name, currentContext: currentContext, image: img)); - } - - @override - toJson() { - throw UnimplementedError(); - } - - @override - Map toPBDF() { - throw UnimplementedError(); - } -} diff --git a/lib/design_logic/text.dart b/lib/design_logic/text.dart deleted file mode 100644 index f7d447e3..00000000 --- a/lib/design_logic/text.dart +++ /dev/null @@ -1,127 +0,0 @@ -import 'package:parabeac_core/design_logic/design_element.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; -import 'package:uuid/uuid.dart'; - -import 'abstract_design_node_factory.dart'; - -class Text extends DesignElement implements DesignNodeFactory, DesignNode { - var attributedString; - - var automaticallyDrawOnUnderlyingPath; - - var dontSynchroniseWithSymbol; - - var lineSpacingBehaviour; - - var textBehaviour; - - var glyphBounds; - - Text({ - UUID, - booleanOperation, - exportOptions, - Frame boundaryRectangle, - bool isFixedToViewport, - bool isFlippedHorizontal, - bool isFlippedVertical, - bool isLocked, - bool isVisible, - layerListExpandedType, - name, - bool nameIsFixed, - resizingConstraint, - resizingType, - double rotation, - sharedStyleID, - bool shouldBreakMaskChain, - bool hasClippingMask, - int clippingMaskMode, - bool maintainScrollPosition, - this.attributedString, - this.automaticallyDrawOnUnderlyingPath, - this.dontSynchroniseWithSymbol, - this.lineSpacingBehaviour, - this.textBehaviour, - this.glyphBounds, - type, - pbdfType = 'text', - style, - }) : super( - UUID: UUID, - name: name, - isVisible: isVisible, - boundaryRectangle: boundaryRectangle, - type: type, - style: style, - ); - - String content; - - @override - String pbdfType = 'text'; - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - DesignNode fromPBDF(Map json) { - return Text( - UUID: json['id'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - isFixedToViewport: json['isFixedToViewport'] as bool, - isFlippedHorizontal: json['isFlippedHorizontal'] as bool, - isFlippedVertical: json['isFlippedVertical'] as bool, - isLocked: json['isLocked'] as bool, - isVisible: json['visible'] as bool, - layerListExpandedType: json['layerListExpandedType'], - name: json['name'] as String, - nameIsFixed: json['nameIsFixed'] as bool, - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: (json['rotation'] as num)?.toDouble(), - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'] as bool, - hasClippingMask: json['hasClippingMask'] as bool, - clippingMaskMode: json['clippingMaskMode'] as int, - maintainScrollPosition: json['maintainScrollPosition'] as bool, - attributedString: json['attributedString'] as Map, - automaticallyDrawOnUnderlyingPath: - json['automaticallyDrawOnUnderlyingPath'] as bool, - dontSynchroniseWithSymbol: json['dontSynchroniseWithSymbol'] as bool, - lineSpacingBehaviour: json['lineSpacingBehaviour'], - textBehaviour: json['textBehaviour'], - glyphBounds: json['glyphBounds'], - type: json['type'] as String, - pbdfType: json['pbdfType'], - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - ); - } - - @override - Future interpretNode(PBContext currentContext) => - Future.value(InjectedContainer( - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - Point(boundaryRectangle.x, boundaryRectangle.y), - name, - Uuid().v4(), - currentContext: currentContext, - constraints: PBIntermediateConstraints(), - )..addChild( - InheritedText(this, name, currentContext: currentContext), - )); -} diff --git a/lib/design_logic/vector.dart b/lib/design_logic/vector.dart deleted file mode 100644 index 694c7765..00000000 --- a/lib/design_logic/vector.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'dart:io'; -import 'package:path/path.dart' as p; - -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/helper/asset_processing_service.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - -import 'abstract_design_node_factory.dart'; -import 'image.dart'; - -class Vector implements DesignNodeFactory, DesignNode, Image { - @override - String pbdfType = 'vector'; - - var layoutAlign; - - var constraints; - - var size; - - var strokes; - - var strokeWeight; - - var strokeAlign; - - var styles; - - var fillsList; - - Vector({ - this.name, - visible, - this.type, - pluginData, - sharedPluginData, - this.layoutAlign, - this.constraints, - Frame this.boundaryRectangle, - this.size, - this.strokes, - this.strokeWeight, - this.strokeAlign, - this.styles, - this.fillsList, - this.UUID, - this.pbdfType = 'vector', - this.style, - }); - - @override - DesignNode createDesignNode(Map json) => fromPBDF(json); - - @override - DesignNode fromPBDF(Map json) { - return Vector( - name: json['name'] as String, - type: json['type'] as String, - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - layoutAlign: json['layoutAlign'] as String, - constraints: json['constraints'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - size: json['size'], - strokes: json['strokes'], - strokeWeight: (json['strokeWeight'] as num)?.toDouble(), - strokeAlign: json['strokeAlign'] as String, - styles: json['styles'], - fillsList: json['fills'] as List, - UUID: json['id'] as String, - pbdfType: json['pbdfType'], - style: json['style'] == null - ? null - : PBStyle.fromPBDF(json['style'] as Map), - )..type = json['type'] as String; - } - - @override - String UUID; - - @override - bool isVisible; - - @override - String name; - - @override - String prototypeNodeUUID; - - @override - PBStyle style; - - @override - String type; - - @override - Future interpretNode(PBContext currentContext) async { - var img = await AzureAssetService().downloadImage(UUID); - - imageReference = AssetProcessingService.getImageName(UUID); - - var pngsPath = - p.join(MainInfo().pngPath, '$UUID.png'.replaceAll(':', '_')); - var file = File(pngsPath)..createSync(recursive: true); - file.writeAsBytesSync(img); - return Future.value( - InheritedBitmap(this, name, currentContext: currentContext)); - } - - @override - toJson() { - throw UnimplementedError(); - } - - @override - Map toPBDF() { - throw UnimplementedError(); - } - - @override - var boundaryRectangle; - - @override - String imageReference; -} diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 5bc8b531..60385ab1 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -1,5 +1,4 @@ import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; @@ -37,13 +36,13 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { } @override - void extractInformation(DesignNode incomingNode) { + void extractInformation(PBIntermediateNode incomingNode) { // TODO: implement extractInformation } @override - PBEgg generatePluginNode( - Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef) { + PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, + PBIntermediateNode originalRef) { return CustomEgg(topLeftCorner, bottomRightCorner, originalRef.name.replaceAll('', '').pascalCase); } diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 3f3d983f..cefc463b 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -1,4 +1,3 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; @@ -41,24 +40,15 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override void addChild(node) { if (node is PBInheritedIntermediate) { - if ((node as PBInheritedIntermediate) - .originalRef - .name - .contains('')) { - getAttributeNamed('leading').attributeNode = node as PBIntermediateNode; + if (node.name.contains('')) { + getAttributeNamed('leading').attributeNode = node; } - if ((node as PBInheritedIntermediate) - .originalRef - .name - .contains('')) { - getAttributeNamed('actions').attributeNode = node as PBIntermediateNode; + if (node.name.contains('')) { + getAttributeNamed('actions').attributeNode = node; } - if ((node as PBInheritedIntermediate) - .originalRef - .name - .contains('')) { - getAttributeNamed('title').attributeNode = node as PBIntermediateNode; + if (node.name.contains('')) { + getAttributeNamed('title').attributeNode = node; } } @@ -79,7 +69,7 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { } @override - void extractInformation(DesignNode incomingNode) {} + void extractInformation(PBIntermediateNode incomingNode) {} } class CustomAppBarAlignment extends AlignStrategy{ @override diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index 19549a52..efd0de5a 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -1,4 +1,3 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; @@ -28,11 +27,11 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { @override - void extractInformation(DesignNode incomingNode) {} + void extractInformation(PBIntermediateNode incomingNode) {} @override - PBEgg generatePluginNode( - Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef) { + PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, + PBIntermediateNode originalRef) { return InjectedBackArrow( topLeftCorner, bottomRightCorner, UUID, originalRef.name, currentContext: currentContext); diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index f45ece1d..eb2538e8 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -1,12 +1,12 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/symbol_instance.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/symbol_master.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; @@ -37,28 +37,32 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { String semanticName; @override - PBEgg generatePluginNode( - Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef) { - var tab = Tab( - topLeftCorner, - bottomRightCorner, - originalRef.name, - currentContext: currentContext, - UUID: originalRef != null && - originalRef.UUID != null && - originalRef.UUID.isNotEmpty - ? originalRef.UUID - : Uuid().v4(), - prototypeNode: PrototypeNode(originalRef?.prototypeNodeUUID), - ); - if (originalRef is! AbstractGroupLayer) { - var designNode = _convertWrapper(originalRef); + PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, + PBIntermediateNode originalNode) { + if (originalNode is PBInheritedIntermediate) { + var tab = Tab( + topLeftCorner, + bottomRightCorner, + originalNode.name, + currentContext: currentContext, + UUID: originalNode != null && + originalNode.UUID != null && + originalNode.UUID.isNotEmpty + ? originalNode.UUID + : Uuid().v4(), + prototypeNode: (originalNode as PBInheritedIntermediate).prototypeNode, + ); + if (originalNode != TempGroupLayoutNode) { + var designNode = _convertWrapper(originalNode); - ///Clean the node so that it doesn't get interpreted as a plugin again. - designNode.interpretNode(currentContext).then(tab.addChild); + ///Clean the node so that it doesn't get interpreted as a plugin again. + // designNode.interpretNode(currentContext).then(tab.addChild); + tab.addChild(designNode); + } + return tab; } - return tab; + return null; } @override @@ -66,24 +70,24 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { return layer; } - DesignNode _convertWrapper(DesignNode node) { + PBIntermediateNode _convertWrapper(PBIntermediateNode node) { /// This is for plugins var str = '${node.name}'; node.name = str.replaceAll(RegExp(r'\<.*?\>'), ''); ///This is for symbol master - if (node is SymbolMaster) { + if (node is PBSharedMasterNode) { /// Convert to AbstractGroup? } ///This is for symbol Instance - if (node is SymbolInstance) {} + if (node is PBSharedInstanceIntermediateNode) {} return node; } @override - void extractInformation(DesignNode incomingNode) { + void extractInformation(PBIntermediateNode incomingNode) { // TODO: implement extractInformation } } diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 84a71956..34fab539 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -1,5 +1,4 @@ import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; @@ -35,10 +34,7 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override void addChild(node) { if (node is PBInheritedIntermediate) { - if ((node as PBInheritedIntermediate) - .originalRef - .name - .contains('')) { + if (node.name.contains('')) { assert(node is! Tab, 'node should be a Tab'); getAttributeNamed('tabs') .attributeNodes @@ -56,14 +52,14 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode( - Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef) { + Point topLeftCorner, Point bottomRightCorner, PBIntermediateNode originalRef) { return InjectedTabBar( topLeftCorner, bottomRightCorner, originalRef.name, UUID, currentContext: currentContext); } @override - void extractInformation(DesignNode incomingNode) { + void extractInformation(PBIntermediateNode incomingNode) { // TODO: implement extractInformation } } diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index ac247d1b..f68f4511 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -5,10 +5,8 @@ import 'package:path/path.dart' as p; import 'package:archive/archive.dart'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_linker.dart'; import 'package:quick_log/quick_log.dart'; @@ -111,54 +109,36 @@ class FlutterProjectBuilder { Future genProjectFiles(String genProjectPath, {List rawImages}) async { - if (MainInfo().figmaProjectID != null && - MainInfo().figmaProjectID.isNotEmpty) { - log.info('Processing remaining images...'); - await FigmaAssetProcessor().processImageQueue(); - } - - // Add all images - if (rawImages != null) { - for (var image in rawImages) { - if (image.name != null) { - var f = File(p.setExtension( - p.join(genProjectPath, 'assets/images/', - image.name.replaceAll(' ', '')), - '.png')); - f.writeAsBytesSync(image.content); - } - } - } - // generate shared Styles if any found - if (project.sharedStyles != null && - project.sharedStyles.isNotEmpty && - MainInfo().exportStyles) { - try { - Directory(p.join(genProjectPath, 'lib/document/')) - .createSync(recursive: true); - - WriteStyleClasses(genProjectPath); - - var s = File(p.join(genProjectPath, 'lib/document/shared_props.g.dart')) - .openWrite(mode: FileMode.write, encoding: utf8); - - s.write('''${FlutterImport('dart:ui', null)} - ${FlutterImport('flutter/material.dart', null)} - - '''); - for (var sharedStyle in project.sharedStyles) { - s.write(sharedStyle.generate() + '\n'); - } - await s.close(); - } catch (e) { - log.error(e.toString()); - } - } + // if (project.sharedStyles != null && + // project.sharedStyles.isNotEmpty && + // MainInfo().exportStyles) { + // try { + // Directory(p.join(genProjectPath, 'lib/document/')) + // .createSync(recursive: true); + + // WriteStyleClasses(genProjectPath); + + // var s = File(p.join(genProjectPath, 'lib/document/shared_props.g.dart')) + // .openWrite(mode: FileMode.write, encoding: utf8); + + // s.write('''${FlutterImport('dart:ui', null)} + // ${FlutterImport('flutter/material.dart', null)} + + // '''); + // for (var sharedStyle in project.sharedStyles) { + // s.write(sharedStyle.generate() + '\n'); + // } + // await s.close(); + // } catch (e) { + // log.error(e.toString()); + // } + // } await Future.wait(PBStateManagementLinker().stateQueue, eagerError: true); await generationConfiguration.generateProject(project); - generationConfiguration.generatePlatformAndOrientationInstance(project); + generationConfiguration + .generatePlatformAndOrientationInstance(project); Process.runSync('rm', ['-rf', '.dart_tool/build'], runInShell: true, diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index e93af0f6..b9e9eacf 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -1,10 +1,6 @@ -import 'package:parabeac_core/eggs/injected_app_bar.dart'; -import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/generation/flutter_project_builder/file_writer_observer.dart'; import 'package:path/path.dart' as p; @@ -16,52 +12,39 @@ class ImportHelper implements FileWriterObserver { /// Traverse the [node] tree, check if any nodes need importing, /// and add the relative import from [path] to the [node] - static Set findImports(PBIntermediateNode node, String path) { - Set currentImports = {}; - if (node == null) { - return currentImports; - } - String id; - if (node is PBSharedInstanceIntermediateNode) { - id = node.SYMBOL_ID; - } else if (node is PBDestHolder) { - id = node.pNode.destinationUUID; - } else { - id = node.UUID; - } + // static Set findImports(PBIntermediateNode node, String path) { + // Set currentImports = {}; + // if (node == null) { + // return currentImports; + // } - var nodePaths = PBGenCache().getPaths(id); - // Make sure nodePath exists and is not the same as path (importing yourself) - if (nodePaths != null && - nodePaths.isNotEmpty && - !nodePaths.any((element) => element == path)) { - var paths = PBGenCache().getRelativePath(path, id); - paths.forEach(currentImports.add); - } + // String id; + // if (node is PBSharedInstanceIntermediateNode) { + // id = node.SYMBOL_ID; + // } else if (node is PBDestHolder) { + // id = node.pNode.destinationUUID; + // } else { + // id = node.UUID; + // } - // Recurse through child/children and add to imports - if (node is PBLayoutIntermediateNode) { - node.children - .forEach((child) => currentImports.addAll(findImports(child, path))); - } else if (node is InheritedScaffold) { - currentImports.addAll(findImports(node.navbar, path)); - currentImports.addAll(findImports(node.tabbar, path)); - currentImports.addAll(findImports(node.child, path)); - } else if (node is InjectedAppbar) { - currentImports.addAll(findImports(node.leadingItem, path)); - currentImports.addAll(findImports(node.middleItem, path)); - currentImports.addAll(findImports(node.trailingItem, path)); - } else if (node is InjectedTabBar) { - for (var tab in node.tabs) { - currentImports.addAll(findImports(tab, path)); - } - } else { - currentImports.addAll(findImports(node.child, path)); - } + // var nodePaths = PBGenCache().getPaths(id); + // // Make sure nodePath exists and is not the same as path (importing yourself) + // if (nodePaths != null && + // nodePaths.isNotEmpty && + // !nodePaths.any((element) => element == path)) { + // var paths = PBGenCache().getRelativePath(path, id); + // paths.forEach(currentImports.add); + // } - return currentImports; - } + // node.attributes.forEach((attribute) { + // attribute.attributeNodes.forEach((attributeNode) { + // currentImports.addAll(findImports(attributeNode, path)); + // }); + // }); + + // return currentImports; + // } List getImport(String UUID) { if (imports.containsKey(UUID)) { diff --git a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart index 36dd80bc..e047ad8e 100644 --- a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart @@ -17,19 +17,21 @@ class PBBoxDecorationHelper extends PBAttributesHelper { buffer.write(PBColorGenHelper().generate(source, generatorContext)); } if (borderInfo != null) { - if (borderInfo['shape'] == 'circle') { + if (borderInfo.shape == 'circle') { buffer.write('shape: BoxShape.circle,'); - } else if (borderInfo['borderRadius'] != null) { + } else if (borderInfo.borderRadius != null) { + // Write border radius if it exists buffer.write( - 'borderRadius: BorderRadius.all(Radius.circular(${borderInfo['borderRadius']})),'); - if ((borderInfo['borderColorHex'] != null) || - (borderInfo['borderThickness'] != null)) { + 'borderRadius: BorderRadius.all(Radius.circular(${borderInfo.borderRadius})),'); + // Write border outline properties if applicable + if (borderInfo.isBorderOutlineVisible && + (borderInfo.color != null || borderInfo.thickness != null)) { buffer.write('border: Border.all('); - if (borderInfo['borderColorHex'] != null) { - buffer.write('color: Color(${borderInfo['borderColorHex']}),'); + if (borderInfo.color != null) { + buffer.write('color: Color(${borderInfo.color.toString()}),'); } - if (borderInfo['borderThickness'] != null) { - buffer.write('width: ${borderInfo['borderThickness']},'); + if (borderInfo.thickness != null) { + buffer.write('width: ${borderInfo.thickness},'); } buffer.write('),'); // end of Border.all( } diff --git a/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart index 53ac5b20..8bd98603 100644 --- a/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_color_gen_helper.dart @@ -9,86 +9,49 @@ class PBColorGenHelper extends PBAttributesHelper { @override String generate(PBIntermediateNode source, PBContext generatorContext) { - var statement = ''; if (source == null) { - return statement; + return ''; } - if (source.auxiliaryData.style != null) { - if (source is InheritedScaffold) { - var scaffold = source; - if (scaffold.auxiliaryData.color == null) { - statement = ''; - } else { - statement = findDefaultColor(scaffold.auxiliaryData.color) != null - ? 'backgroundColor: ${findDefaultColor( - scaffold.auxiliaryData.color)},\n' - : 'backgroundColor: Color(${scaffold - .auxiliaryData.color}),\n'; - } - } else if (source.auxiliaryData.color == null) { - statement = ''; - } else { - if (source is! InheritedContainer) { - statement = findDefaultColor(source.auxiliaryData.color) != null - ? 'color: ${findDefaultColor( - source.auxiliaryData.color)},\n' - : 'color: Color(${source - .auxiliaryData.color}),\n'; - } else if ((source as InheritedContainer).isBackgroundVisible) { - statement = findDefaultColor(source.auxiliaryData.color) != null - ? 'color: ${findDefaultColor( - source.auxiliaryData.color)},\n' - : 'color: Color(${source - .auxiliaryData.color}),\n'; - } else { - statement = ''; - } - } - } else { - if (source is InheritedScaffold) { - var scaffold = source; - if (scaffold.auxiliaryData.color == null) { - statement = ''; - } else { - statement = findDefaultColor(scaffold.auxiliaryData.color) != null - ? 'backgroundColor: ${findDefaultColor( - scaffold.auxiliaryData.color)},\n' - : 'backgroundColor: Color(${scaffold - .auxiliaryData.color}),\n'; - } - } else if (source.auxiliaryData.color == null) { - statement = ''; - } else { - if (source is! InheritedContainer) { - statement = findDefaultColor(source.auxiliaryData.color) != null - ? 'color: ${findDefaultColor( - source.auxiliaryData.color)},\n' - : 'color: Color(${source - .auxiliaryData.color}),\n'; - } else if ((source as InheritedContainer).isBackgroundVisible) { - statement = findDefaultColor(source.auxiliaryData.color) != null - ? 'color: ?? ${findDefaultColor( - source.auxiliaryData.color)},\n' - : 'color: Color(${source - .auxiliaryData.color}),\n'; - } else { - statement = ''; - } - } + var color = source.auxiliaryData.color?.toString(); + if (color == null) { + return ''; + } + + var defaultColor = findDefaultColor(color); + + // Check type of source to determine in which attribute to place the color + switch (source.runtimeType) { + case InheritedScaffold: + return defaultColor != null + ? 'backgroundColor: $defaultColor,\n' + : 'backgroundColor: Color($color),\n'; + + case InheritedContainer: + if ((source as InheritedContainer).isBackgroundVisible) { + return defaultColor != null + ? 'color: $defaultColor,\n' + : 'color: Color($color),\n'; + } + return ''; + default: + return defaultColor != null + ? 'color: $defaultColor,\n' + : 'color: Color($color),\n'; } - return statement; } + /// Finds default color based on common hex patterns. + /// + /// Returns `null` if no pattern was found String findDefaultColor(String hex) { switch (hex) { case '0xffffffff': return 'Colors.white'; - break; case '0xff000000': return 'Colors.black'; - break; + default: + return null; } - return null; } } diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 450ccb98..356fc195 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -1,5 +1,4 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -19,8 +18,8 @@ class MiddlewareUtils { if (node is PBSharedMasterNode && (node.overridableProperties?.isNotEmpty ?? false)) { node.overridableProperties.forEach((prop) { - overrideVars += 'final ${prop.friendlyName};'; - overrideAttr += 'this.${prop.friendlyName}, '; + overrideVars += 'final ${prop.propertyName};'; + overrideAttr += 'this.${prop.propertyName}, '; }); stateBuffer.write(MiddlewareUtils.generateEmptyVariable(node)); stateInitializers.write( @@ -35,7 +34,7 @@ class MiddlewareUtils { if (variationNode is PBSharedMasterNode && (variationNode.overridableProperties?.isNotEmpty ?? false)) { variationNode.overridableProperties.forEach((prop) { - var friendlyName = SN_UUIDtoVarName[prop.propertyName] ?? 'NOTFOUND'; + var friendlyName = prop.propertyName; overrideVars += 'final $friendlyName;'; overrideAttr += 'this.$friendlyName, '; }); diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index 276d5f2d..d4a9d31f 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -1,4 +1,3 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -21,9 +20,9 @@ abstract class PBEgg extends PBVisualIntermediateNode { List layoutInstruction(List layer) => layer; - PBEgg generatePluginNode( - Point topLeftCorner, Point bottomRightCorner, DesignNode originalRef); + PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, + PBIntermediateNode originalNode); - void extractInformation(DesignNode incomingNode); + void extractInformation(PBIntermediateNode incomingNode); } diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 66440c4a..3d9a65ba 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -1,22 +1,12 @@ -import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; -import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; -import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; -import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/entities/style/text_style.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/override_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; import 'package:quick_log/quick_log.dart'; -import 'package:parabeac_core/controllers/main_info.dart'; import 'package:recase/recase.dart'; class PBSymbolInstanceGenerator extends PBGenerator { @@ -37,8 +27,11 @@ class PBSymbolInstanceGenerator extends PBGenerator { PBSymbolStorage().getSharedMasterNodeBySymbolID(source.SYMBOL_ID); // recursively generate Symbol Instance constructors with overrides - buffer.write(genSymbolInstance(source.UUID, source.overrideValuesMap, - masterSymbol.parametersDefsMap, source.managerData)); + buffer.write(genSymbolInstance( + source.UUID, + source.sharedParamValues, + generatorContext, + )); // end of return (); buffer.write(';\n'); @@ -69,12 +62,12 @@ class PBSymbolInstanceGenerator extends PBGenerator { } String genSymbolInstance( - String UUID, - Map mapOverrideValues, - Map mapParameterValues, - PBGenerationViewData managerData, - {bool topLevel = true, - String UUIDPath = ''}) { + String UUID, + List overrideValues, + PBContext context, { + bool topLevel = true, + String UUIDPath = '', + }) { if ((UUID == null) || (UUID == '')) { return ''; } @@ -97,72 +90,19 @@ class PBSymbolInstanceGenerator extends PBGenerator { symName = PBInputFormatter.formatLabel(symName, destroyDigits: false, spaceToUnderscore: false, isTitle: true); - // if this symbol is overridable, then put variable name + null check - var overrideProp = SN_UUIDtoVarName[UUID + '_symbolID']; - if (overrideProp != null) { - buffer.write('$overrideProp ?? '); - } - buffer.write(symName.pascalCase); buffer.write('(\n'); buffer.write('constraints,\n'); - // need to iterate through master symbol parametersDefsMap to pass parent variables down to children - - masterSymbol.parametersDefsMap.forEach((overrideName, smParameter) { - var ovrValue = ''; - overrideName = UUIDPath + overrideName; - if (mapOverrideValues.containsKey(overrideName)) { - var param = mapOverrideValues[overrideName]; - switch (param.type) { - case PBSharedInstanceIntermediateNode: - ovrValue = genSymbolInstance( - param.value, - mapOverrideValues, - mapParameterValues, - managerData, - topLevel: false, - UUIDPath: '$UUIDPath${param.UUID}/', - ); - break; - case InheritedBitmap: - ovrValue = '\"assets/${param.value["_ref"]}\"'; - break; - case TextStyle: - // hack to include import - managerData.addImport(FlutterImport( - 'document/shared_props.g.dart', MainInfo().projectName)); - ovrValue = '${SharedStyle_UUIDToName[param.value]}.textStyle'; - break; - case Style: - // hack to include import - managerData.addImport(FlutterImport( - 'document/shared_props.g.dart', MainInfo().projectName)); - ovrValue = '${SharedStyle_UUIDToName[param.value]}'; - break; - case String: - ovrValue = '\"${param.value}\"'; - break; - default: - log.info( - 'Unknown type ${param.type.toString()} in parameter values for symbol instance.\n'); - } - } - // get parameter name to pass to widget constructor - var friendlyName = SN_UUIDtoVarName[ - PBInputFormatter.findLastOf(smParameter.propertyName, '/')]; - var paramName = ''; - // check if parent widget has parameter to pass down to children - if (managerData.hasParams && - mapParameterValues.containsKey(smParameter.propertyName)) { - // yes, so pass down with optional null check - paramName = friendlyName; - if (ovrValue != '') { - paramName += ' ?? '; - } - } - if ((ovrValue != '') || (paramName != '')) { - buffer.write('$friendlyName: $paramName$ovrValue,\n'); + // Make sure override property of every value is overridable + overrideValues.removeWhere((value) { + var override = OverrideHelper.getProperty(value.UUID, value.type); + return override == null || override.value == null; + }); + _formatNameAndValues(overrideValues, context); + overrideValues.forEach((element) { + if (element.overrideName != null && element.initialValue != null) { + buffer.write('${element.overrideName}: ${element.value},'); } }); @@ -170,4 +110,31 @@ class PBSymbolInstanceGenerator extends PBGenerator { return buffer.toString(); } + + /// Traverses `params` and attempts to find the override `name` and `value` for each parameter. + void _formatNameAndValues( + List params, PBContext context) { + params.forEach((param) { + var overrideProp = OverrideHelper.getProperty(param.UUID, param.type); + + if (overrideProp != null) { + param.overrideName = overrideProp.propertyName; + // Find and reference symbol master if overriding a symbol + if (param.type == 'symbolID') { + var instance = PBSharedInstanceIntermediateNode( + UUID: param.UUID, + SYMBOL_ID: param.initialValue, + name: param.overrideName, + overrideValues: [], + sharedParamValues: [], + ); + var code = instance.generator.generate(instance, context); + param.value = code; + // Add single quotes to parameter value for override + } else if (!param.value.contains('\'')) { + param.value = '\'${param.value}\''; + } + } + }); + } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index cfed23b8..6c14146d 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -104,7 +104,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { relPath = p.join(tree.identifier, platformFolder, tree.identifier); } if (tree.isHomeScreen()) { - await _setMainScreen(tree, relPath, project.projectName); + await _setMainScreen(tree, relPath, MainInfo().projectName); } await applyMiddleware(tree); } @@ -114,7 +114,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { Future generateProject(PBProject pb_project) async { var processInfo = MainInfo(); _head = CommandGenMiddleware( - generationManager, this, _importProcessor, pb_project.projectName); + generationManager, this, _importProcessor, MainInfo().projectName); ///First we are going to perform a dry run in the generation to ///gather all the necessary information diff --git a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart index c02f663a..8a2925d9 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart @@ -1,6 +1,5 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/template_strategy/pb_template_strategy.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -20,8 +19,8 @@ class StatelessTemplateStrategy extends TemplateStrategy { if (node is PBSharedMasterNode && node.overridableProperties.isNotEmpty) { node.overridableProperties.forEach((prop) { - overrides += 'this.${prop.friendlyName}, '; - overrideVars += 'final ${prop.friendlyName};'; + overrides += 'this.${prop.propertyName}, '; + overrideVars += 'final ${prop.propertyName};'; }); } return ''' diff --git a/lib/generation/generators/visual-widgets/pb_align_gen.dart b/lib/generation/generators/visual-widgets/pb_align_gen.dart new file mode 100644 index 00000000..16e9f25f --- /dev/null +++ b/lib/generation/generators/visual-widgets/pb_align_gen.dart @@ -0,0 +1,37 @@ +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/generators/pb_generator.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_align.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:quick_log/quick_log.dart'; + +class PBAlignGenerator extends PBGenerator { + var log = Logger('Align Generator'); + PBAlignGenerator() : super(); + + @override + String generate(PBIntermediateNode source, PBContext generatorContext) { + if (source is InjectedAlign) { + var buffer = StringBuffer(); + buffer.write('Align('); + + buffer.write( + 'alignment: Alignment(${source.alignX.toStringAsFixed(2)}, ${source.alignY.toStringAsFixed(2)}),'); + + try { + source.child.currentContext = source.currentContext; + buffer.write( + 'child: ${source.child.generator.generate(source.child, generatorContext)},'); + } catch (e, stackTrace) { + MainInfo().sentry.captureException( + exception: e, + stackTrace: stackTrace, + ); + log.error(e.toString()); + } + + buffer.write(')'); + return buffer.toString(); + } + } +} diff --git a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart index d7070451..efdcaa8e 100644 --- a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart @@ -1,9 +1,11 @@ +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/override_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:path/path.dart' as p; class PBBitmapGenerator extends PBGenerator { var _sizehelper; @@ -17,15 +19,21 @@ class PBBitmapGenerator extends PBGenerator { var buffer = StringBuffer(); buffer.write('Image.asset('); - if (SN_UUIDtoVarName.containsKey('${source.UUID}_image')) { - buffer.write('${SN_UUIDtoVarName[source.UUID + '_image']} ?? '); - } else if (SN_UUIDtoVarName.containsKey('${source.UUID}_layerStyle')) { - buffer.write('${SN_UUIDtoVarName[source.UUID + '_layerStyle']} ?? '); + + var imageOverride = OverrideHelper.getProperty(source.UUID, 'image'); + var styleOverride = OverrideHelper.getProperty(source.UUID, 'layerStyle'); + if (imageOverride != null) { + buffer.write('${imageOverride.propertyName} ?? '); + } else if (styleOverride != null) { + buffer.write('${styleOverride.propertyName} ?? '); } - // buffer.write( - // '\'assets/${source is InheritedBitmap ? source.referenceImage : ('images/' + source.UUID + '.png')}\', ${_sizehelper.generate(source, generatorContext)})'); + + var imagePath = source is InheritedBitmap + ? p.relative(source.referenceImage, from: MainInfo().genProjectPath) + : ('assets/images/' + source.UUID + '.png'); + buffer.write( - '\'assets/${source is InheritedBitmap ? source.referenceImage : ('images/' + source.UUID + '.png')}\')'); + '\'$imagePath\', ${_sizehelper.generate(source, generatorContext)})'); return buffer.toString(); } } \ No newline at end of file diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index 11582130..f5843977 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -18,8 +18,7 @@ class PBContainerGenerator extends PBGenerator { buffer.write(PBSizeHelper().generate(source, generatorContext)); - if (source.auxiliaryData.borderInfo != null && - source.auxiliaryData.borderInfo.isNotEmpty) { + if (source.auxiliaryData.borderInfo != null) { buffer.write(PBBoxDecorationHelper().generate(source, generatorContext)); } else { buffer.write(PBColorGenHelper().generate(source, generatorContext)); diff --git a/lib/generation/generators/visual-widgets/pb_flexible_gen.dart b/lib/generation/generators/visual-widgets/pb_flexible_gen.dart index b41e73a8..5e7b7f75 100644 --- a/lib/generation/generators/visual-widgets/pb_flexible_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_flexible_gen.dart @@ -9,8 +9,7 @@ class PBFlexibleGenerator extends PBGenerator { PBFlexibleGenerator() : super(); @override - String generate( - PBIntermediateNode source, PBContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is Flexible) { var buffer = StringBuffer(); buffer.write('Flexible('); @@ -25,5 +24,6 @@ class PBFlexibleGenerator extends PBGenerator { buffer.write(')'); return buffer.toString(); } + return ''; } } diff --git a/lib/generation/generators/visual-widgets/pb_text_gen.dart b/lib/generation/generators/visual-widgets/pb_text_gen.dart index 9f66a731..cffbfced 100644 --- a/lib/generation/generators/visual-widgets/pb_text_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_text_gen.dart @@ -1,12 +1,12 @@ -import 'package:parabeac_core/design_logic/color.dart'; +import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/override_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -class PBTextGen extends PBGenerator with PBColorMixin { +class PBTextGen extends PBGenerator { PBTextGen() : super(); @override @@ -24,15 +24,18 @@ class PBTextGen extends PBGenerator with PBColorMixin { var text = source.text; buffer.write('$text, \n'); } else { - if (SN_UUIDtoVarName.containsKey('${source.UUID}_stringValue')) { - buffer.write('${SN_UUIDtoVarName[source.UUID + '_stringValue']} ?? '); + var textOverride = + OverrideHelper.getProperty(source.UUID, 'stringValue'); + if (textOverride != null) { + buffer.write('${textOverride.propertyName} ?? '); } buffer .write(('\'${source.text?.replaceAll('\n', ' ') ?? ''}\'') + ',\n'); } buffer.write('style: '); - if (SN_UUIDtoVarName.containsKey('${source.UUID}_textStyle')) { - buffer.write(SN_UUIDtoVarName[source.UUID + '_textStyle'] + ' ?? '); + var styleOverride = OverrideHelper.getProperty(source.UUID, 'textStyle'); + if (styleOverride != null) { + buffer.write('${styleOverride.propertyName} ?? '); } buffer.write('TextStyle(\n'); @@ -53,12 +56,7 @@ class PBTextGen extends PBGenerator with PBColorMixin { buffer.write('letterSpacing: ${source.letterSpacing},\n'); } if (source.auxiliaryData.color != null) { - if (findDefaultColor(source.auxiliaryData.color) == null) { - buffer.write('color: Color(${source.auxiliaryData.color}),'); - } else { - buffer - .write('color: ${findDefaultColor(source.auxiliaryData.color)},'); - } + buffer.write(PBColorGenHelper().generate(source, generatorContext)); } buffer.write('),'); diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index ac6aab81..6608a3ab 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -30,18 +30,17 @@ class PBPrototypeAggregationService { factory PBPrototypeAggregationService() => _instance; + List screens = []; + /// Iterates through `_unregNodes` to find whether any [PBPrototypeNode]'s /// `destinationUUID` matches the `node` UUID. If there is a match, populate /// the [PrototypeNode]. Future analyzeIntermediateNode(PBIntermediateNode node) async { if (node is InheritedScaffold) { + screens.add(node); + ///check if any of the [IntermediateNode]s looking for a destination contains their destination. - for (var _pNode in _unregNodes) { - if (_pNode.prototypeNode.destinationUUID == node.UUID) { - _pNode.prototypeNode.destinationName = node.name; - _addDependent(_pNode as PBIntermediateNode, node); - } - } + iterateUnregisterNodes(node); } else if (node is PrototypeEnable) { var page = _storage.getPageNodeById( (node as PrototypeEnable).prototypeNode.destinationUUID); @@ -104,4 +103,25 @@ class PBPrototypeAggregationService { return iNode; } } + + // TODO: change it on the future + // This temporal solution solves the issue for topological sorting + // when two screens link each other, but one comes first + // and does not get linked to the proper button on the screen + Future linkDanglingPrototypeNodes() async { + if (_unregNodes.isNotEmpty) { + for (var screen in screens) { + iterateUnregisterNodes(screen); + } + } + } + + void iterateUnregisterNodes(PBIntermediateNode node) { + for (var _pNode in _unregNodes) { + if (_pNode.prototypeNode.destinationUUID == node.UUID) { + _pNode.prototypeNode.destinationName = node.name; + _addDependent(_pNode as PBIntermediateNode, node); + } + } + } } diff --git a/lib/generation/prototyping/pb_prototype_node.dart b/lib/generation/prototyping/pb_prototype_node.dart index ac8b036a..38d8655c 100644 --- a/lib/generation/prototyping/pb_prototype_node.dart +++ b/lib/generation/prototyping/pb_prototype_node.dart @@ -7,6 +7,10 @@ class PrototypeNode { PrototypeNode(this.destinationUUID, {this.destinationName}); String destinationUUID; String destinationName; - factory PrototypeNode.fromJson(Map json) => _$PrototypeNodeFromJson(json); + factory PrototypeNode.fromJson(Map json) => + _$PrototypeNodeFromJson(json); Map toJson() => _$PrototypeNodeToJson(this); + + static PrototypeNode prototypeNodeFromJson(String prototypeNodeUUID) => + PrototypeNode(prototypeNodeUUID); } diff --git a/lib/input/assets/image-conversion-error.png b/lib/input/assets/image-conversion-error.png deleted file mode 100644 index 0ec0d86ff13b6dd0fe133e7ada70310c2043b259..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16739 zcmZ{Lby$>J^zMg9h)5U+NGc&pNC*PbC?X0fNQXGm-4a7d8GwQkN{XO_bfGp@H6;FpoN0M9c2XtHhV`qQwwVo1Udf-`%3CYoh;LLBlT;qo;|s?%P6Gbkjr-A z_xbz0{(1+Xc+qUw$aPLXk~ECPSA=#otmcQA*)ILKYI468Zl5>&==E__Os- z#=I*lHcCCo$cv7vHy0m~?c_a28yYg*l+m;N3<<&q6TMJw>cBL9KY6vGTguC;>gWpZ zqLWXUEvJ>x7w+S&f`hpsVj*UteDN#N4lhq}1a8JX9!NTRT*lGBbt}|q$k@+}G*shZ z!j&7m6MEXV#+sKjep~#0`QGxizy|}(D|QZ=DyOspoXVbVAiJ~QC4JO0q4Hq`^W zkUmsVQbZ2W|B|XcM#4Ks>~H8eAqf9D^naqqsWPtcCYiJH?Q3M?lxOHTg>M-r#lTw( z&eyb^73^$mOl+MI1xFKOXOl;4ZWhkwY)Z+xJ||GOc|pI&xpzw{-gB7IuKMlB~`^X5rk-0LS%7Ye(a-qPvKwtk?{eW+LTKKb+K z(9V>Ohq`CJ>#AOsdq$qlMJ^XYL*ANug#9Y#)qsGlz0p{a+=6$5kKD{$H}=Z2cfZax zwJbE{4_BEj>^N0$FwC%*^nV^7e?)}%ez~uyX*t)EC*=_~#B?1&=GuCCKCQ32UcP*J zZL`dSWQ-*B!-pRP$Mnj|xB_CtH<6BC|I_Q&CkO58jf(5g)#NQ~dt@ zyTf%NM6g$A(Q8fO?9p=fMBgO_M3y(>^XFq0xPfoEml5Q>Y}|*f(Vn|jR+*ZgbyEWZ z4r3Rb632cJBky(PZx#7M}aWUA2R z%s_7(UkN=K71JGc^+-{>A#2=oHZM|yrcs`maZKyz-Wx5$R~(F*5l+fZLWi&G^kU@!0lY~7whQUT+=zmhnck(u3&PgbZB zEyoTihzWQK7*!8MiOFtKB42D($wSL#GBV4vo=EFWrG0;XIx{Wpx{HfTabX8%tr>!> z=Q^!wDJwrErKBGzFk!hP=T`gfeG)NJn-1PIKR>Tq=9uc}=xFVJ%x}D4_1SCUS;w+* z$Ff>!&tnLiD4%}m9UdN@;!`WKBpUdF{QPm(iu(oz&9S5i+u=VeD<$sUWuU-MizfBxl%Pn8j8Rz0V< z&=rPV^q^&A#Hbvta#9)O85Kq!D4X>x2v4sE8;Ok;&B(}D{X$IL<9I37`xNppGCo<* zugPqoht9)H)tnhMY2NoE$$}@iZjtxf&kW@`K5RBJdvTx4w`U{(A7d}dR_EBbr;je> zeOXtJ!@Cl#toR4;WVZ5CCr?7U=+$hRf2bnIjXJ)KJOkqxwcbLqB##%Dl$3$6S<84N zIdT^-6n(Nl>w!&KuFIY34C49tT+lEH5y?Bwc;YU};G>O~qJQ5Ah;nyw zDqv(}eEsT`v0k%%`=zNNFW&t?^uv^35W!Q7CtmS6e=O|anL!-)XG4)r^p0n8$s_Q!RIwImdB;NjlCq!(z_cb)mb8>z! ze#nx3R*1*;=W8Az%DOH}BSd!f>3DxeA-;k~Qt};ak^HPY=3!|PHy77&FzVE+8|0zO zN{VVN$4{R&^ZZBxt4uO$x)_f};hfBIdCV^DtEvGkmJK}4m;9n)Ks_G9U3pYkM@NU! zf*4^X4^0jn;^Yo!y|i}$*)%mvxM66R@Oy0RGIo3QQ~7;H7m~pvtWh&FmXJ|s;fa%M zB3#b&#dL=l7#Ps=B$3C+e{?IX7DU}N{@RW{Qxn{ZncR>Qns|tj*h9k29~2c-YPe5iWt`(rtlD%>dr}=uRGqf z#PAfn=v!D+R8&~CqH9qT86`c9a7x(w;^>M~PH~U#-+#mMc!WsLkQm}2RQLg z1Ox=cNG=GvG!AAI-GVHj*y?7*%k6TU7jptOr-)%UlXlwqwtB@Gbp;9hXv_nK{@79B z>FMdW;!a#-hh@L9iv;;E(8t%A)k-Cnm*qevP(AD$@<_}4g}BJEldDwlm$*xbXpG0T zKs4rE5owN&Ss>V^=I7s23S(jiukvCO38E_>6E{A73LbN%%w%X_AS)<{wBL}J&xyiA z7R?-L;N=1JS58I`?3weOc!?lh+!D-Rg{Yz;BF;wRIvtL%AalIq0rhwA=X5nSqXukC z25iO1An)=D2;_`OUJ(?0Mf{t117Cs9F_P(D#6WuZ(h^m+I$ik7H6%QIQb>|SY7-tr zV>MU)&6etR3NaIj6bJgoQHkLCp1@=azm#ZCF{qJjZ)q77j!KzcVfRX_t~QK_QDc_9 zqc;&yugLFFw&BYl9T^>cdL8@m!w1;5Z&JpmPj_zKd?q9$bcMbUkI6|zi{JLP2kgf| z7D;*s&Y0A2wSdf0M~5Lg9dSOo60441_BnpygrvXO+{}$b$e>BL*Mz&fJ9C}G5%{pA zyuNpaO}+=Zb=rTyqyxrvKF_L z`DTfMZM(3fBr`9st*cuWHY3FqyOQ4B*%^45OLJRGNxY>0wj9}eMGPjz2I~xY>?A9z zT3lvm>G%RdAP|a8E@)|KUF6|`tjR{vBYrjN(ajxN-V^6*nm#EQY(wV@9aaKM8wX&(Bey^zD&1r{r^1OrM*xF4O0S zQe=P0mnJhSOT*p03`(B0=ds4d#+$0Dn)>=o+yQhF@>`j)uv?EeQBlVki77k^3nabL zva_=>H_j+%`;Nfk2d@cikb`^B1RDJmU3&#ay05GIw*A+y%T5!wR1fnx2Si5JngvlY zqi{);0)LE;kI&N9ws`GwQ-ajHDEELAb^Vi<>dfG{YpWMwT_$E`nZ?CXCy1QYuU!j- z+D`wLRClVdL-@@ow2x%d{%|MkrQ3tRW z;4%Pm55Uq7iN6X7*0wCgLWQa|qbX?GYGQCdq&r2fs}c{(F1D|D?oSnvmC8>m{iFvx z=lm2o4=i&jS6C!1E9+JSHbq}nPU!`l3rBix?n`3-Pgb%0%#3xXa(lkz7SWrAJvEVb zVS7wLL1AqXd$2nx(|upd;F{dWz%cFcfP>Y5RyM|eJpFEj^}Fs}0G;n&s^e*AQ9I=4 z3+d_3^!D~fNY96=$SHlWw6-p^;dc@i;bLd^J0T~hl%;a}c9GN)Ab=!K@=(904;Y*Q zp_9L0V8m$6G9?94slbMbMiT$2VuB*a3h|@2;0GPc^Z{v&Jou6awzz-iPSWq+5Bm)j z?%j(315JCv{+IX#1>1_ZI{a?@-E;^!0KnqbkG521k>rVf1-g*wzNC{!`3)OAfIW24 zG7{@fg=nkBsKKfAfaUJsY44LK%4OvXi;yNIotuJX)P|=A(UJ#!W@j_qyyflf-Lr9f zld={*i(ze&n(3^`?r74bGGd+>;!llR3U)ZpQrZ=EF%ZI4w2} z@+ditvtFb_=-I&<@W%pLzbK<$v4}kZAuDk<0pf3>B|Z}xL)Dv``WNDippXO4NqJXHLZbrqP6xRaRE+*=Y8f$xDU0#2@|q z6rVwV z4z$OAU+mVdrpt!R57!tiR_|o*Z?*bZHov{RJuoT#@zpsc%k~e-<=ZovE?-Gb#}#=) z!`hW&l=J4ImgQi%%l60%HHHVZfk#8@>#s}y2vI)i%yyWhs;H|ygFyFe`#qw`t|Ea9UUE;S5-R4$}Gq)bDj;9s|Ly}aPkw}S&b#Jca_%Pq0 z1qVD@y0kxMCbP0FJ<*yt{Q05nK9+FNNKiFV+GcA2sz80A#jiu&EwtyZAJ)L1Iddj7 zD=W*kY9Ibhzq7G8Nqme#LRN0kTW)c81820~-cw)}-qzP=$t3C8be@lIKA(PXN=Zh@ z(#k4S{i7-a@B{V3`|Dykv*m-f;oXG}W7lymlP&R9*1h@PuXyj4whay0qTkg919nHP zPc*;d8(t}Bm7XmMiF)&fA()y~6mq}|Vlpavl_=ijEyJo)tH8I6k;!cO5kvv4*ZUEZ zy+GgT$-~rV+|PWmJl5cuZuPXDlO_Q6*&*2h^^E;U;hjkcb(wYNXq@({J@d$cuRVqy~Y*)-DyOlxgDSl;<( zODo5a*Fba0cK zzfaegmsO^xH)48cIy3pYvD?!hT_C1(q+OdYcTb(J*}Nv(ut@E*`J^F#XR*e}X#Y<% zU-tnTo=U9P4$PLGUDfwsTEQn!)4s&J4Nbe4_xchM^F|LlG%#=1p01|Bi-N&fa4j+i zUIrf1sf;q-m8Q*aQ{TTo3+3Ju`x%;}wh-ELyB@Z7Bzxtv*(>f>({8_;*vOM~91lSq zI-Fq8{8-Gii9XzfT4p!*?YnndvS+z2Q8AMf*#+uENUy}UYV&V&QHVV+eDmw0n%nFe zMB8=S61{g~c3qN-l_|I1iMnU~>g)69s_F0R)3|rEHJiVmV{IqrmBRby*F8=hg8a5LJ&+sIQb|(6!O2Nd*&Hiuw(B9)5XSr~j9IeK zreD;iCs)p{dMizOcS#|!zf?cFU?00Wb+@y#(>*IXHnx|r@3}UUdd9A@EyuswZde*e zNKp!3=ql@}a1$V5hOTLF>|*2mfV{;Y*YJu8)p&_iAE1l2XN?XrxDy_q9hq;%#&fGB z6zVV59u-)f-GYj`x4%q#E0~J;H}Me)3Eze3&WlS6JXM}#i#21gsMV!9>RHHcRDGUT zTxMPqJcex9oj1sycUJ8rEUhaXhCPv&x}3?d$?E9tzR1npFv+==gPphf+0xPl6kNJ- zU693}@y3ko>~$Ud&g%596o2>M-;UID70eLSP*<02+9C+}Sm-n@R&5yWP5SJA1k~r! zcI|Zhnzo*vUNoPxT?s7}%hjpwS;vY&@6V?J;Ffto&V<}Bc9`};YUfpl*@Bdj30d27FuSl2V6*!Letu0r&z6>!&Qo}H+y>DdJkb?h;3s*bYxdUr zqi|;!8CN3{cfb9~b9!RJVF6t7%y3Oj!=EyzN!_r!(I4D~+?A-MR$mS;ekC|sOflT{7g1@BzLJp-Dl!pT_>tTevdp5izpd1ZKAbkPI zX?S{8P_as9{rTev9^Y&=RCfQ-%oji6wM?VEpO~!#DNnRJL)leGn2T4jb! z9%a5ca)RqT_yNWp7z-#bNl-Co!R`_czXKpiePG>R3ideI+mPz=*6eog~2MvHk{)7x0;=2KbOqRmkf9P{{FmG*U-S=vvMRC2>}}i zTZZOM1F($}&S$97{jHdtVRWk?rk)bVN`mk?BebLa!~4ZtY6){2+mPLhtX*oB>(4|* z5ALkZeuQ|C?>6-OJiN0BHu^-y>V?OY<>bZ+crQQKEq6`_$6;C$`~mHvaO>5v%fzhU z>h_i31eU;tMKR-A);iSH(m#AqEE)E$Xu#+dTem@7$MjEoD-i88}E8$&fdKBrEfp52;ETy(6ZXX~?XWDb#kLVD~T zv=-GX@rzS?8^hg@Pm7G}NDW+jO&A3q22}471gyXVP@K?W*~zbyKb|$IQ*0dzp;NVQ zzd5bulc7^!Iz8w%d>?QN!05}5e$bdadSqT3a0JCbSXGTNn`NWn_G2hj$u zu^t-}n2-?$p+_OGHm9!qt(8eD@OvgE_+_6sI0UHwZ)JR{yRr?e%36Y1y®)T|ff zOnVORB-DqVQ8Fg;Wf_T(^nYJot}8a^9BErdpv(C_@H26Ll^eT-Gtz{S4a9wu-(lFy z+@Fn_0|OM@!r7GXF+pA{b#!tfxK@ZKA^2lW#X&6YJM$$jb;raG&u>+u&-s4Zr~^d< zRQw3^O;-Sd+()CMyCKng+XAg^;QM#=^xmO`36iq;bbBhJq-z#I)MxuwB2?4buOtYx zx50pqpx60SSlBU^XO&Z>*(!5T$zQYUnA6WH;e3OHgv4XL*G!6K796D5Za5o)(lLq1 z*FWqIP+9oP-TGsBUP~iib*nszz*y}BCnhNmjk2;bT?ml|OitDMTidEN%^E`$7$8V* zPn`q%s)FyM6gPC4LDa0-;QMHRF^W5WIDY)N|N4G^fB#yW5~~H_=NsL;hk-C~%7R2= zzB<*04s_~YFr>74O$dicm{qvWxAzrU6?v>#V*fO9_Z8c`L;niYQs@~mRrEADqxIXz z_TsL(-?OV)ivkc-Gc^`2(*;g_*`l4pz-`c_eCqx4tKRgseTB+U`Jr}p0k|)6Uoll~ zPmMOrzzNjo1HJk4#}E7|Eq&TzJwdNDnpc!;vSuxDf(zxd{0b2b!$t?&-M$G{of-F| zTAcveF~A>}%WPoB%bR22dbU0bM!>MZejkd6iMegP{R^m>(Ds3{?h?2crYTmqVR9ev zld1JUY1^MIBhUHEI2+*0r@ICFtFaY?b%E;5_k``+w{O?0t4R^M9dt|WlVPqo<#bTt zwpcu{zBF2QT}9=&1B8{XbhUZg`+@{B=(XxY#fG4oM?8ALEZOyVGTyCxSD%vQY7eF# z{CUU4`rMi@34M?;H0il8n$z(f1+2uN6wY#Nsw|9E#`YEzB<e(2J(46FJ+WoFL) zQE`M$?>cN~`1_Y#Tyyi~^~K@gd4b`+KHYQY&ei2$kHG^r$0OBvp9ghr%WQt7-jy&F zsM*aYtV83H%UkVt^0sn4m>?9&6`4LB>gA)8baWorA=K-~#D@S3`?kh!ZBz{J@pF(! zMaZZ_BoF=>@?6yM?%jpzehjx?RWw6vF+JZ~z&#=`41V8FFX?J6yYp5M^S4_I$2Pqa zYjxa%9zAgp?W0Q9`>dpjD>jBarMhgatwr+l^UGacTz^47T6Dwx;*<|y2kichOW}1; zS3I2eIT#K$8)W=-@hPLiB%t4nhX zc2pn5r}qM_ZdRE;`|l%mM%AXt=#xWh4)zx7zdj)g1*Cfh2C0`IQHtjneVH)nYylRp z+=a6Hv)-hZpOuxBu=mmvR_$y(IC7>d_Fv559l(aBS-M3(=>dc{cx(*1CAM{SO}NQz ztZn?fnB#1H@Z((gCaH}3pO;W;{ zQ2-C~U}M;)h7jEZ;iFJK4D%~`r^%M0fsJ=|)fQ#90g@~O{J4yQzcV z$XoxoZ!8R2x%ZYpEgtdT|AP}agLcHadU~N%o*Rq;l}qvs^S*%5&g|`MZ1kA!ZLb*) zuRzH%E=xo^vIY{Vx6-H=5WNEf6QXZHAl%r{Q&-274cFGnC-%onxcrQPW}P7AlS%cU zy4q{leUdq6r?=cCvs*Lajm*JTYt*bAbZL%zP-AtAITGRg!(Gtfbokmr&4G7f!!&Rn z8$A<{c#eHaI(_QY)38qnH<=r*8J;znlm&(r zn?}enUT?f$B*QB0gyM_+kqC}V7kEmtT+MyWp%I{0Rw^DnVD0aaji00i z%L(^9a}Ep51daf(!UGl{6?HHnR)cC08XPle5&;77K#QMcBI&kJI4}&wX>Mij82zO$ zj%77l+W;`2zOI$Eket>}f>FN*FZ$(lzz^!M>|fQ`oks!eEawdD25!1Uuo{VKGUhuyWYpDBNjOt3646&j#WihId!VjfCsYa zE1b?Uflq4Pz5A-69JaRl_yAauf`RU-wiJS6S>?X_MP4ZVYqOh=%*@=}`2qB-8Xc?| zMTJ)ZGgCgD_RhJHGkR*`on4nxtJFudrDL}Wy*_J30R)*{A~3gn(Ith20oIAoO3rF# z78F3+rDJHbR8r(L8hF~ZOcff5t5I8)HiqtmH&J|DkZB6`t4y02adi8gT1N95c{AAn zv9^j5N^o_P+cR1uD_k*@A-v#7@E2ggXdTD`qGjp==eg^-k>Pz8rD^jf|a?&1vz zE)!TJ_5)*=KjX?ZT`OXwMRvp07cN}5=j~lRoHGg(L%ePIG}kd!X?>_R5AO_N3cb^S z`P&t>>^P4j05Lb$wF1qbELzlE=lcjn1P92~YoB^=eUYjj?@bwUml}i(5*{jWV-s&3z zPT?pCnX+-JIgtmTR?Xvz#SJK;WL{+@$;onP*JTT>BNoik{enSwb$d3)bD*SZ#Q$ie z?P3m}Uh!kzGmv}c`Oq=N)v z9#Clyd1OQB*~#(|(8*VX%-#)53QSUq!w5%?9D$!)>e+|3U~Sg>cUy`QpI({UfJ5-P zu=M+rC_x|(WwvPU5j>7}ZN_A8*bS)8C>%AbG*h2Iq~YL!L>X-A^_w@Tm6caN>lWQa z!A`|ub>_!JZ{2g(U*ry$E)0}O%?QxUqX*^3zqT-_hn5BcW_WMGt!h1Ax*O20%U?hs z3V@`bo?&CAQw18ij}0CWbt@9LG7FBK5!L1|d3&gf3J^9+Jjz0($?T3&>sEVh>EIxa z77I?zehyav?h$j;!wk58MnJ?|s&Stdv5TJDKv=AS=0ZE$6C9SMYRG*5mY+Y>rU|q@ zQFYy*BXVwFcKei_-7<-memu+q`Si3Qfv_0!L^uOIsw3SU!Kvc4fHtk$^L9S7d0sua z#y^{yoWCv4{rVVA2tSi)g4(>H@^?HZH}~wB;mx3iKTwP{A!lxs8$dFKF_Z?(+M#_$ z=jb5Rk(Y` zFY=b@M(IyJgK~{0WYkofF5?puGZ4^6%&p667Rn}BaE+MV%MZViqo083jGX6fG`Qn` z`})3Ml`&-XTJkgWma z^<_O{Jy3=BHhd0B2$*o`ZSyZVSm-JN+qDBzwx?SIxfggRl(}KeAM1e6{-tw)xX9_Z zt>8Z?f=3*{=a-8tQW^T5Z`p)Zs%^uf78BLlvq3Knv#>(EUyKvPRn=OT9?E6Bht5PB@N>rp z)r=p@F47lyZ z#KgqQ8Z{&Vs1n6`YCEaD)nD5%w6WRRg!TAWV`1u^T{gjpPFMcSUheAbv-pe+qKuJQ~?42gzR&$_fEP+-5NLOfrqm$YkdBQS_ z1$2m#N1s5mlv}L^<3hFvzz!RiI1Oyf_jiBBR`347NjzRk0{CC#wrGe}*zNY{>XU`@ z%_>93jvZs^uilz?_Y;RxhiVIOCIx_vC1iG8=tRB2KXr;b&;fe?A8EfBMX^Ikp7Fmu z{*<^a4*5zvR~7=5M)_cG)9}2Nr6q3(A207}*7L7>By}d5 zJRoJFUfLNM8nP^<+AB*eR<5kZFM0u?3J69Tc7v{8WdUKjc=4i2dU`th;6AkK+k1;X zi+Q{CXY4voS1$$fZ#V!!rps?sWO=`5h#P!$#QdMpI(!_mJ34=C_yauZR?*`A-i{R{ zO%|LH%v5r#)YzihOioUv*_)PuKq$a#2gZjwe`gtcL#?^SbyuUH!&QRz0}q@f>z|Dy z;GHApQhTE#t?Qs3jl%8md`km(jw3*?M}gZp4AH>E_ws$;;Cw6e9XJBaA67kOP^6(h zRAM)rTZx+EOIzis{s*=`Fr0Y3rdYynO9>3r*w%VcDoQAuX*sY0#*|e78cKi-cI%kno&vyUEekQfgbt})U<+u zddd&(TZCvSmYqg5@8hcpvkF0!%RlOU#$PF2aZgHeB8MqT<2WyWH0~AcN9ZNHAlve> zRsf7IG;cdQKUAgnQ7y3x?60Axml@3BaRWt|4ckr=P3-lj$R`hssEB-9vP*wcKsD&d zr=KJcct9bBn~b^Yo=|DDOBsSuFh(ggv5#Ws=D zubUSI1SS=i-0xtqQrt+`wJ6CE;>I6SyquiZA~gQhuFHaYU`YwmfL%O&1S7WWn@HfK)yULEF2kmh(hAQ_evuJz!tdu zv9Yl?adAyg?MuNef#*|>c=r5x(WAzQ-1!|pGM1MdAkTKZa46nT8LSMi^4fCLGgL4zFleB@vyfhA+Z0TtWNu+`7n0m(lK3#yS62TiWDT_S zX5yFcQ&32-fx4(Vh0LK8R9`$G1OPBT`Ntvv4xnV7EV+L^ii4Aj3+iuJq+c!^rL|qG zn3z~*a`M;W?w5&)tx`^_FtM`u>^%{6S6Xj~pYaaDS^w*Wl#K9G4 zh)eqe?mV8$YbXsQ*0ZN(E>1deLcX!`&AG9)7YP|*rRbKdb3Qq4})4`KAV68T!}HJ7ovR9CC-#yTB;3vZAMns z_yaa`_-fMZz!tfEM$1Zi@J>Q`FOMCN3UTCj@T2;!f%O23ETP|tLpD=aK=TXA%ahJm zA_kKMEi5dYMdV9B+ejgS2aRS3h`8)SR@Fnp3q5H-@SX+ zSPwTq8JcVo_8=BGm=9`ptiAW~L=+Maso>k!16q?R=!3&-1wmqC8Bd%HJ~qK^3E(&q#dB|v|5 zNFGBo+Z5#i!*wOLTUVTiPN%#8EmSxy;}h-40M^$at2ym&GIA z|50I5ti%$>KQcAV0KJwpGr)!YVp+<%Bo``en4P@B5oSscQ{TZGgD@${3VzFC>Lgi1 zQ4=R9^t|9il-1N0eGaJ+Kyfx~I8<(%5yKtACyX1zOAIO^}7r1I1&l zH(4?;pr4wW3VZrA8lbE(Gds(P?W5*IU0GgEiMO!n-Me?4c>IHYs~9OyQ9dWOA58@*Y)r<17qZ?S6{y({?>ox)F~+iOdwLz0I3wY8pzsWdulm1=zoa^Gs>ESjMvnU zMEY>&^%4U}yWU5M!+Bys#zn#`2l~8=Z z2BD#$5pxxb^)FAeiO>lcWr~zDQRFFET*t&rw7%Lo>~R%F(^F2 z13O_+?~Opv!IAy#+Hu$hy*$RZM{W}p13ra>3Bz$9ZyYZ9(#vh$8Xt-9444{FuIC3( z=o~?04MM~7Q+Ge4rPW7mHAx1e;(DjE$eC~7zxVEA%AHzBHbAaFMY zQF}~c1^Z(C!)!r7Dr=^?>34hcg)lAem@FLf)XmAp7%&B&b1PznB$AwL?txUc$AT~yo_TXq#q$JGokYm{H1hm2kr=WDuRvv>mKWC6uzjNoy*QBI| zVpNM69o;XQSjGVj_eF8>*qsNm0YY_VprM9V`wE+2h^hnC9bH{ZPjgD&A6?>J_1QF^ zAjSNm4)$kJhZCZqK&g=N#>hGr=>o|7VJsUjLei2NPJ#(RRr%}JFYzO?C($PV)|0@c z*d=ytt|s(r`~j^n$RbCV7suxUE=*Q6fC=fJ=YoxC(@KNLdL|~i8gwM$^hoVb%EVV3 z(YWtKPwx#VP)9=d-!Jhs_Q<`bPoF};8GD4}?WWqP%PkHtxWRNgj$C)@Rj-f?NK@vM z1rfGAE9o^L{&I)3#5UeQ{#Q;)QsRP>xbn0&*c2wI#dC>E3=|%qW+(NHgh$H-C&CIx z9zobM{Cg#gM@sQy=^bY6cM=ISuwt5crIC}TPAykmJIWlPVPvERhZACzZU)%}6%6`^ zjj(BR-9$fm4;0MrqDSP84vK;WL!6-nMV-sxAGxdY0i(KQ_ih71!wd2Npkc((+cTcJ z6RyGa_D`8*KQU6EpT>~FHr~GiogfG;{aNmz_sAagOM&zo33vipeNelT!21%e$8JO2 zk-Z|$?qv$&G{#F0kWpc8HtjS?GLQ-)f&ojhKfYXXmI0IF2#$hr#Im=FJB}VbI-PZ0 zPDu?^b+~y~z`oDnf(93@^smbc$!=dOJ05jsSwy^k{rX$n1Y#W>6LY?#pHKOlz9bC@ z>hA#e-QQ#}p?xRF2C>&)&YfOQ=@r+G05By^d(!zpcf!>C)|Fr@=lXP_k@5O4j_PyF z0V)fIa5Tt}cyhzv{i3Ih92{eo0KtJtabZVue=@pjzP2`EWHk*RR5+iVd>9A3Up(8guB<}fA z?8x(Sm4(9$2r}H8w;9ju!siSw!sZBB(G)tWV(OffBuNCmh{vLoWoxSzTr7ePsT_>4fJJat51+1SBhn6rBCeft^RXAva1Up13DJx7b%C4 z!-*(VL!ndgpjJ2stqy+vzgq-b8 z00f^EfE;7$M4kLcPosEs+8v5~{aF+t4ulmjAlcYTBteWP!0mxulBgcmP;_}#koiOr zcFG4f(3yO7+jUUg%~8tU>u5X#h;Q#bZm)Vte-p3sJUp-Z=QTAo>EIg4$kY-;Loq&{ zhEe#z7bGZ+$hVG08q=J&fj#Xw)R08q$t}}PbFJ2YPHbBqk$Ah5OEd8>3;^N|h zSY9SAJQx$o3|#&)9kcr4OH^D%`Z1vON?H;)r0bwCdWL7afz5=bgKm9^VcKXVy`Ncn zEXKbDFM`OrrKY9z4NW#Kz&f0tL5L%G^*knNjMd*&%U%+Pdujaqs*nwh`|X-YacFdr zgL>I?v^LOqFo%x>3+y5E3Ee;6T(prKF*Sej%dC|MIov{-C`hRQa9?ma!KQ577Vdkr zf7}rLpysJ~2%)(!VK0i_;h@~wukGW>h6{V8!KY%*nmdXkNKr#9pEG25RQjOiiiF$+ zFek+{Ds0R%1*z*+tPm$}G_)`+r{@2@M|qnV>EY{x3g<}u_n_5dMuj7+%Z@Q+Y@f`h z^T1#*Jq;s72>ujYQ)}^OdA1b$vIswa%P$i+C=d=nU^19dAxnmbZ4%U^WMpK_v6cQT zykl^c4@gz;am3(R+EQ$ik)s=2pa7tUoRtG@zQ1cD`ZU=O&w?1~3h5-k^L=j+0I4ic zS0D`JZcl@gI+DxKj^i`y1Z7_Z}khu*+|d*Z4PDj0&^xt^RvQ!{a4f znfL-O=$j(W=T)B)Xo%)}ya@XES3i!Fe3I0i0&ilVup|5DEy~0^r^jw~+%GawFQsX0 zs-J>HFjsN&5)3}ZfY&WtlSREVgfu?KHMru{T*M>K%c-DFfB%$uug#-(&2$C5=t}yX z388TTX?{cmw2}p4!OV#7Nd7r5t~rt_C&=vxd04KIqnHBbhA%OqSTR069@dWoKW>A& zy-e`)i2p@vxCPieN`c50TKzpb&mXmB@|1vnqy1J{Ltbm)0k)=#5p7|HEEAR{_F6mI7pegm3(MERPk KVz&GP|NjFd>+XF3 diff --git a/lib/input/figma/entities/abstract_figma_node_factory.dart b/lib/input/figma/entities/abstract_figma_node_factory.dart deleted file mode 100644 index 00dcecdf..00000000 --- a/lib/input/figma/entities/abstract_figma_node_factory.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:parabeac_core/input/figma/entities/layers/boolean_operation.dart'; -import 'package:parabeac_core/input/figma/entities/layers/canvas.dart'; -import 'package:parabeac_core/input/figma/entities/layers/component.dart'; -import 'package:parabeac_core/input/figma/entities/layers/ellipse.dart'; -import 'package:parabeac_core/input/figma/entities/layers/frame.dart'; -import 'package:parabeac_core/input/figma/entities/layers/group.dart'; -import 'package:parabeac_core/input/figma/entities/layers/instance.dart'; -import 'package:parabeac_core/input/figma/entities/layers/line.dart'; -import 'package:parabeac_core/input/figma/entities/layers/rectangle.dart'; -import 'package:parabeac_core/input/figma/entities/layers/slice.dart'; -import 'package:parabeac_core/input/figma/entities/layers/star.dart'; -import 'package:parabeac_core/input/figma/entities/layers/text.dart'; - -import 'layers/figma_node.dart'; -import 'layers/regular_polygon.dart'; -import 'layers/vector.dart'; - -class AbstractFigmaNodeFactory { - static final String FIGMA_CLASS_KEY = 'type'; - - static final List _figmaNodes = [ - BooleanOperation(), - Canvas(), - Component(), - FigmaEllipse(), - FigmaFrame(), - Group(), - Instance(), - FigmaLine(), - FigmaRectangle(), - FigmaSlice(), - FigmaStar(), - FigmaText(), - FigmaVector(), - FigmaRegularPolygon(), - ]; - - AbstractFigmaNodeFactory(); - - static FigmaNode getFigmaNode(Map json) { - var className = json[FIGMA_CLASS_KEY]; - if (className != null) { - for (var figmaNode in _figmaNodes) { - if (figmaNode.type == className) { - return figmaNode.createFigmaNode(json); - } - } - } - return null; - } -} - -abstract class FigmaNodeFactory { - String type; - FigmaNode createFigmaNode(Map json); -} diff --git a/lib/input/figma/entities/layers/boolean_operation.dart b/lib/input/figma/entities/layers/boolean_operation.dart deleted file mode 100644 index 76018f2b..00000000 --- a/lib/input/figma/entities/layers/boolean_operation.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/group_node.dart'; -import 'package:parabeac_core/design_logic/image.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_style.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:quick_log/quick_log.dart'; -import 'figma_node.dart'; - -part 'boolean_operation.g.dart'; - -@JsonSerializable(nullable: true) -class BooleanOperation extends FigmaVector - implements FigmaNodeFactory, GroupNode, Image { - @override - @JsonKey(ignore: true) - Logger log; - @override - List children; - String booleanOperation; - - @override - String type = 'BOOLEAN_OPERATION'; - - @override - var boundaryRectangle; - - BooleanOperation({ - List this.children, - booleanOperation, - type, - FigmaStyle style, - Frame this.boundaryRectangle, - String UUID, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing, - }) : super( - style: style, - UUID: UUID, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing) { - log = Logger(runtimeType.toString()); - pbdfType = 'boolean_operation'; - } - - @override - FigmaNode createFigmaNode(Map json) => - BooleanOperation.fromJson(json); - factory BooleanOperation.fromJson(Map json) => - _$BooleanOperationFromJson(json); - @override - Map toJson() => _$BooleanOperationToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - imageReference = FigmaAssetProcessor().processImage(UUID); - - return Future.value( - InheritedBitmap(this, name, currentContext: currentContext)); - } - - @override - String imageReference; - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'boolean_operation'; -} diff --git a/lib/input/figma/entities/layers/boolean_operation.g.dart b/lib/input/figma/entities/layers/boolean_operation.g.dart deleted file mode 100644 index 469dde06..00000000 --- a/lib/input/figma/entities/layers/boolean_operation.g.dart +++ /dev/null @@ -1,71 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'boolean_operation.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -BooleanOperation _$BooleanOperationFromJson(Map json) { - return BooleanOperation( - children: (json['children'] as List) - ?.map((e) => - e == null ? null : FigmaNode.fromJson(e as Map)) - ?.toList(), - booleanOperation: json['booleanOperation'], - type: json['type'], - style: json['style'] == null - ? null - : FigmaStyle.fromJson(json['style'] as Map), - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - UUID: json['id'] as String, - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..name = json['name'] as String - ..pluginData = json['pluginData'] - ..sharedPluginData = json['sharedPluginData'] - ..isVisible = json['visible'] as bool ?? true - ..layoutAlign = json['layoutAlign'] as String - ..constraints = json['constraints'] == null - ? null - : FigmaConstraints.fromJson(json['constraints'] as Map) - ..size = json['size'] - ..strokes = json['strokes'] - ..strokeWeight = (json['strokeWeight'] as num)?.toDouble() - ..strokeAlign = json['strokeAlign'] as String - ..styles = json['styles'] - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$BooleanOperationToJson(BooleanOperation instance) => - { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'style': instance.style, - 'layoutAlign': instance.layoutAlign, - 'constraints': instance.constraints, - 'size': instance.size, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'styles': instance.styles, - 'fills': instance.fillsList, - 'children': instance.children, - 'booleanOperation': instance.booleanOperation, - 'type': instance.type, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'imageReference': instance.imageReference, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/canvas.dart b/lib/input/figma/entities/layers/canvas.dart deleted file mode 100644 index f57c5fae..00000000 --- a/lib/input/figma/entities/layers/canvas.dart +++ /dev/null @@ -1,98 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/group_node.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - -import '../abstract_figma_node_factory.dart'; - -part 'canvas.g.dart'; - -@JsonSerializable(nullable: true) -class Canvas extends FigmaNode implements FigmaNodeFactory, GroupNode { - @override - String type = 'CANVAS'; - - Canvas({ - this.name, - this.type, - List this.children, - this.backgroundColor, - this.prototypeStartNodeID, - this.prototypeDevice, - this.exportSettings, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing, - }) : super( - name, - true, - type, - null, - null, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'artboard'; - } - // Last two nulls are used for Figma plugins - - @override - String name; - - @override - List children; - - dynamic backgroundColor; - - dynamic prototypeStartNodeID; - - dynamic prototypeDevice; - - dynamic exportSettings; - - Canvas createSketchNode(Map json) => Canvas.fromJson(json); - factory Canvas.fromJson(Map json) => _$CanvasFromJson(json); - - @override - Map toJson() => _$CanvasToJson(this); - - @override - FigmaNode createFigmaNode(Map json) => Canvas.fromJson(json); - - @override - var boundaryRectangle; - - @override - String prototypeNodeUUID; - - @override - @JsonKey(ignore: true) - var style; - - @override - Future interpretNode(PBContext currentContext) { - assert(false, 'We don\'t product pages as Intermediate Nodes.'); - return null; - } - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'artboard'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/figma/entities/layers/canvas.g.dart b/lib/input/figma/entities/layers/canvas.g.dart deleted file mode 100644 index b453a1d1..00000000 --- a/lib/input/figma/entities/layers/canvas.g.dart +++ /dev/null @@ -1,50 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'canvas.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Canvas _$CanvasFromJson(Map json) { - return Canvas( - name: json['name'] as String, - type: json['type'] as String, - children: (json['children'] as List) - ?.map((e) => - e == null ? null : FigmaNode.fromJson(e as Map)) - ?.toList(), - backgroundColor: json['backgroundColor'], - prototypeStartNodeID: json['prototypeStartNodeID'], - prototypeDevice: json['prototypeDevice'], - exportSettings: json['exportSettings'], - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..pluginData = json['pluginData'] - ..sharedPluginData = json['sharedPluginData'] - ..isVisible = json['visible'] as bool ?? true - ..boundaryRectangle = json['boundaryRectangle'] - ..pbdfType = json['pbdfType'] as String; -} - -Map _$CanvasToJson(Canvas instance) => { - 'id': instance.UUID, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'type': instance.type, - 'name': instance.name, - 'children': instance.children, - 'backgroundColor': instance.backgroundColor, - 'prototypeStartNodeID': instance.prototypeStartNodeID, - 'prototypeDevice': instance.prototypeDevice, - 'exportSettings': instance.exportSettings, - 'boundaryRectangle': instance.boundaryRectangle, - 'transitionNodeID': instance.prototypeNodeUUID, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/component.dart b/lib/input/figma/entities/layers/component.dart deleted file mode 100644 index b803f6b2..00000000 --- a/lib/input/figma/entities/layers/component.dart +++ /dev/null @@ -1,154 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_shared_master_node.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; -import 'package:parabeac_core/input/figma/entities/layers/frame.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; - -part 'component.g.dart'; - -@JsonSerializable(nullable: true) -class Component extends FigmaFrame - with SymbolNodeMixin - implements AbstractFigmaNodeFactory, PBSharedMasterDesignNode { - @override - String type = 'COMPONENT'; - Component({ - name, - isVisible, - type, - pluginData, - sharedPluginData, - Frame boundaryRectangle, - style, - fills, - strokes, - strokeWeight, - strokeAlign, - cornerRadius, - FigmaConstraints constraints, - layoutAlign, - size, - horizontalPadding, - verticalPadding, - itemSpacing, - this.overrideProperties, - List children, - FigmaColor backgroundColor, - this.symbolID, - this.overriadableProperties, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing, - }) : super( - name: name, - isVisible: isVisible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - boundaryRectangle: boundaryRectangle, - style: style, - fills: fills, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - cornerRadius: cornerRadius, - constraints: constraints, - layoutAlign: layoutAlign, - size: size, - horizontalPadding: horizontalPadding, - verticalPadding: verticalPadding, - itemSpacing: itemSpacing, - children: children, - backgroundColor: backgroundColor, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'symbol_master'; - } - - // make sure only store unique UUID overrides with Map - @override - var overrideProperties; - - @override - FigmaNode createFigmaNode(Map json) => - Component.fromJson(json); - factory Component.fromJson(Map json) => - _$ComponentFromJson(json); - @override - Map toJson() => _$ComponentToJson(this); - - List _extractParameters() { - var ovrNames = {}; - var sharedParameters = []; - overrideProperties ??= []; - for (var prop in overrideProperties) { - if (!ovrNames.contains(prop.overrideName)) { - var properties = extractParameter(prop.overrideName); - sharedParameters.add(PBSharedParameterProp( - name, - properties['type'], - null, - prop.canOverride, - prop.overrideName, - properties['uuid'], - properties['default_value'])); - ovrNames.add(prop.overrideName); - } - } - return sharedParameters; - } - - @override - Future interpretNode(PBContext currentContext) { - var sym_master = PBSharedMasterNode( - this, - UUID, - name, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - overridableProperties: _extractParameters() ?? [], - currentContext: currentContext, - ); - return Future.value(sym_master); - } - - @override - List overriadableProperties; - - @override - String symbolID; - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'symbol_master'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } - - @override - var isFlowHome; -} diff --git a/lib/input/figma/entities/layers/component.g.dart b/lib/input/figma/entities/layers/component.g.dart deleted file mode 100644 index 76c754bd..00000000 --- a/lib/input/figma/entities/layers/component.g.dart +++ /dev/null @@ -1,83 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'component.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Component _$ComponentFromJson(Map json) { - return Component( - name: json['name'], - isVisible: json['visible'] ?? true, - type: json['type'], - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - strokes: json['strokes'], - strokeWeight: json['strokeWeight'], - strokeAlign: json['strokeAlign'], - cornerRadius: json['cornerRadius'], - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - layoutAlign: json['layoutAlign'], - size: json['size'], - horizontalPadding: json['horizontalPadding'], - verticalPadding: json['verticalPadding'], - itemSpacing: json['itemSpacing'], - overrideProperties: json['overrideProperties'], - children: (json['children'] as List) - ?.map((e) => - e == null ? null : FigmaNode.fromJson(e as Map)) - ?.toList(), - backgroundColor: json['backgroundColor'] == null - ? null - : FigmaColor.fromJson(json['backgroundColor'] as Map), - symbolID: json['symbolID'] as String, - overriadableProperties: json['overriadableProperties'] as List, - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String - ..isFlowHome = json['isFlowHome'] ?? false; -} - -Map _$ComponentToJson(Component instance) => { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'children': instance.children, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'cornerRadius': instance.cornerRadius, - 'constraints': instance.constraints, - 'layoutAlign': instance.layoutAlign, - 'size': instance.size, - 'horizontalPadding': instance.horizontalPadding, - 'verticalPadding': instance.verticalPadding, - 'itemSpacing': instance.itemSpacing, - 'backgroundColor': instance.backgroundColor, - 'fills': instance.fillsList, - 'imageReference': instance.imageReference, - 'type': instance.type, - 'overrideProperties': instance.overrideProperties, - 'overriadableProperties': instance.overriadableProperties, - 'symbolID': instance.symbolID, - 'pbdfType': instance.pbdfType, - 'isFlowHome': instance.isFlowHome, - }; diff --git a/lib/input/figma/entities/layers/ellipse.dart b/lib/input/figma/entities/layers/ellipse.dart deleted file mode 100644 index ed4b6223..00000000 --- a/lib/input/figma/entities/layers/ellipse.dart +++ /dev/null @@ -1,113 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/image.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:quick_log/quick_log.dart'; -import 'figma_node.dart'; - -part 'ellipse.g.dart'; - -@JsonSerializable(nullable: true) -class FigmaEllipse extends FigmaVector - implements AbstractFigmaNodeFactory, Image { - @override - String imageReference; - @override - @JsonKey(ignore: true) - Logger log; - - @JsonKey(ignore: true) - var fills; - - @override - String type = 'ELLIPSE'; - FigmaEllipse({ - String name, - bool visible, - String type, - pluginData, - sharedPluginData, - style, - layoutAlign, - FigmaConstraints constraints, - Frame boundaryRectangle, - size, - this.fills, - strokes, - strokeWeight, - strokeAlign, - styles, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing, - }) : super( - name: name, - visible: visible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - style: style, - layoutAlign: layoutAlign, - constraints: constraints, - boundaryRectangle: boundaryRectangle, - size: size, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - styles: styles, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'oval'; - log = Logger(runtimeType.toString()); - } - - @override - FigmaNode createFigmaNode(Map json) => - FigmaEllipse.fromJson(json); - factory FigmaEllipse.fromJson(Map json) => - _$FigmaEllipseFromJson(json); - @override - Map toJson() => _$FigmaEllipseToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - imageReference = FigmaAssetProcessor().processImage(UUID); - return Future.value( - InheritedBitmap(this, name, - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width)), - ); - } - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'oval'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/figma/entities/layers/ellipse.g.dart b/lib/input/figma/entities/layers/ellipse.g.dart deleted file mode 100644 index cb6e0515..00000000 --- a/lib/input/figma/entities/layers/ellipse.g.dart +++ /dev/null @@ -1,63 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'ellipse.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaEllipse _$FigmaEllipseFromJson(Map json) { - return FigmaEllipse( - name: json['name'] as String, - type: json['type'] as String, - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - style: json['style'], - layoutAlign: json['layoutAlign'], - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - size: json['size'], - strokes: json['strokes'], - strokeWeight: json['strokeWeight'], - strokeAlign: json['strokeAlign'], - styles: json['styles'], - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..isVisible = json['visible'] as bool ?? true - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$FigmaEllipseToJson(FigmaEllipse instance) => - { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'style': instance.style, - 'layoutAlign': instance.layoutAlign, - 'constraints': instance.constraints, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'size': instance.size, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'styles': instance.styles, - 'fills': instance.fillsList, - 'imageReference': instance.imageReference, - 'type': instance.type, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/figma_font_descriptor.dart b/lib/input/figma/entities/layers/figma_font_descriptor.dart deleted file mode 100644 index 1638b10c..00000000 --- a/lib/input/figma/entities/layers/figma_font_descriptor.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:parabeac_core/design_logic/pb_font_descriptor.dart'; - -class FigmaFontDescriptor implements PBFontDescriptor { - @override - String fontName; - - @override - num fontSize; - - String fontWeight; - - String fontStyle; - - num letterSpacing; - - @override - Map rawAttributes; - - FigmaFontDescriptor( - this.fontName, - this.fontSize, - this.rawAttributes, - this.fontWeight, - this.fontStyle, - this.letterSpacing, - ); -} diff --git a/lib/input/figma/entities/layers/figma_node.dart b/lib/input/figma/entities/layers/figma_node.dart deleted file mode 100644 index 9e1f7a9f..00000000 --- a/lib/input/figma/entities/layers/figma_node.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -import '../abstract_figma_node_factory.dart'; - -@JsonSerializable(nullable: true) -abstract class FigmaNode implements DesignNode { - @JsonKey(name: 'id') - @override - String UUID; - - @override - String name; - - @override - String type; - - var pluginData; - - var sharedPluginData; - - @override - @JsonKey(name: 'visible', defaultValue: true) - bool isVisible; - - @override - @JsonKey(name: 'transitionNodeID') - String prototypeNodeUUID; - @JsonKey(nullable: true) - num transitionDuration; - @JsonKey(nullable: true) - String transitionEasing; - - FigmaNode( - this.name, - this.isVisible, - this.type, - this.pluginData, - this.sharedPluginData, { - this.UUID, - this.prototypeNodeUUID, - this.transitionDuration, - this.transitionEasing, - }); - @override - Map toJson(); - factory FigmaNode.fromJson(Map json) => - AbstractFigmaNodeFactory.getFigmaNode(json); - @override - Future interpretNode(PBContext currentContext); -} diff --git a/lib/input/figma/entities/layers/figma_paragraph_style.dart b/lib/input/figma/entities/layers/figma_paragraph_style.dart deleted file mode 100644 index 1a15584a..00000000 --- a/lib/input/figma/entities/layers/figma_paragraph_style.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:parabeac_core/design_logic/pb_paragraph_style.dart'; - -class FigmaParagraphStyle implements PBParagraphStyle { - @override - int alignment = ALIGNMENT.LEFT.index; - - FigmaParagraphStyle({this.alignment}); -} diff --git a/lib/input/figma/entities/layers/frame.dart b/lib/input/figma/entities/layers/frame.dart deleted file mode 100644 index 8625bdde..00000000 --- a/lib/input/figma/entities/layers/frame.dart +++ /dev/null @@ -1,190 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/artboard.dart'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/group_node.dart'; -import 'package:parabeac_core/design_logic/image.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; -import 'package:parabeac_core/input/figma/entities/layers/group.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/figma/helper/style_extractor.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; - -part 'frame.g.dart'; - -@JsonSerializable(nullable: true) -class FigmaFrame extends FigmaNode - with PBColorMixin - implements FigmaNodeFactory, GroupNode, PBArtboard, Image { - @override - @JsonKey(name: 'absoluteBoundingBox') - var boundaryRectangle; - - @override - @JsonKey(ignore: true) - var style; - - @override - List children; - - @JsonKey(ignore: true) - var fills; - - var strokes; - - double strokeWeight; - - String strokeAlign; - - double cornerRadius; - - FigmaConstraints constraints; - - String layoutAlign; - - var size; - - double horizontalPadding; - - double verticalPadding; - - double itemSpacing; - - @override - PBColor backgroundColor; - - @override - String type = 'FRAME'; - - @JsonKey(ignore: true) - bool isScaffold = false; - - @override - @JsonKey(nullable: true, defaultValue: false) - var isFlowHome = false; - - FigmaFrame({ - name, - isVisible, - type, - pluginData, - sharedPluginData, - Frame this.boundaryRectangle, - this.style, - this.fills, - this.strokes, - this.strokeWeight, - this.strokeAlign, - this.cornerRadius, - this.constraints, - this.layoutAlign, - this.size, - this.horizontalPadding, - this.verticalPadding, - this.itemSpacing, - List this.children, - String UUID, - FigmaColor this.backgroundColor, - String transitionNodeID, - num transitionDuration, - String transitionEasing, - String prototypeNodeUUID, - }) : super( - name, - isVisible, - type, - pluginData, - sharedPluginData, - UUID: UUID, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'group'; - } - @JsonKey(ignore: true) - List points; - - @JsonKey(name: 'fills') - List fillsList; - - @override - FigmaNode createFigmaNode(Map json) { - var node = FigmaFrame.fromJson(json); - node.style = StyleExtractor().getStyle(json); - return node; - } - - factory FigmaFrame.fromJson(Map json) => - _$FigmaFrameFromJson(json); - @override - Map toJson() => _$FigmaFrameToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - /// TODO: change `isHomeScreen` to its actual value - if (isScaffold) { - return Future.value(InheritedScaffold( - this, - currentContext: currentContext, - name: name, - isHomeScreen: isFlowHome, - )); - } else { - var tempGroup = Group( - name: name, - isVisible: isVisible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - boundaryRectangle: boundaryRectangle, - style: style, - fills: fills, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - cornerRadius: cornerRadius, - constraints: constraints, - layoutAlign: layoutAlign, - size: size, - horizontalPadding: horizontalPadding, - verticalPadding: verticalPadding, - itemSpacing: itemSpacing, - children: children, - UUID: UUID, - backgroundColor: backgroundColor, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ); - - return Future.value(tempGroup.interpretNode(currentContext)); - } - } - - @override - String imageReference; - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'group'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/figma/entities/layers/frame.g.dart b/lib/input/figma/entities/layers/frame.g.dart deleted file mode 100644 index 087da5fd..00000000 --- a/lib/input/figma/entities/layers/frame.g.dart +++ /dev/null @@ -1,78 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'frame.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaFrame _$FigmaFrameFromJson(Map json) { - return FigmaFrame( - name: json['name'], - isVisible: json['visible'] ?? true, - type: json['type'], - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - strokes: json['strokes'], - strokeWeight: (json['strokeWeight'] as num)?.toDouble(), - strokeAlign: json['strokeAlign'] as String, - cornerRadius: (json['cornerRadius'] as num)?.toDouble(), - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - layoutAlign: json['layoutAlign'] as String, - size: json['size'], - horizontalPadding: (json['horizontalPadding'] as num)?.toDouble(), - verticalPadding: (json['verticalPadding'] as num)?.toDouble(), - itemSpacing: (json['itemSpacing'] as num)?.toDouble(), - children: (json['children'] as List) - ?.map((e) => - e == null ? null : FigmaNode.fromJson(e as Map)) - ?.toList(), - UUID: json['id'] as String, - backgroundColor: json['backgroundColor'] == null - ? null - : FigmaColor.fromJson(json['backgroundColor'] as Map), - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - prototypeNodeUUID: json['transitionNodeID'] as String, - ) - ..isFlowHome = json['isFlowHome'] ?? false - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$FigmaFrameToJson(FigmaFrame instance) => - { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'children': instance.children, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'cornerRadius': instance.cornerRadius, - 'constraints': instance.constraints, - 'layoutAlign': instance.layoutAlign, - 'size': instance.size, - 'horizontalPadding': instance.horizontalPadding, - 'verticalPadding': instance.verticalPadding, - 'itemSpacing': instance.itemSpacing, - 'backgroundColor': instance.backgroundColor, - 'type': instance.type, - 'isFlowHome': instance.isFlowHome, - 'fills': instance.fillsList, - 'imageReference': instance.imageReference, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/group.dart b/lib/input/figma/entities/layers/group.dart deleted file mode 100644 index 9835f5b7..00000000 --- a/lib/input/figma/entities/layers/group.dart +++ /dev/null @@ -1,191 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/image.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; -import 'package:parabeac_core/input/figma/entities/layers/frame.dart'; -import 'package:parabeac_core/input/figma/entities/layers/text.dart'; -import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; -import 'package:quick_log/quick_log.dart'; - -part 'group.g.dart'; - -@JsonSerializable(nullable: true) - -/// Class that represents a Figma Group. -/// The reason this class implements Image is because Groups can hold multiple vectors -/// which we need to convert into images. -class Group extends FigmaFrame implements AbstractFigmaNodeFactory, Image { - @JsonKey(ignore: true) - Logger log; - @override - String type = 'GROUP'; - - @override - String imageReference; - - Group( - {name, - isVisible, - type, - pluginData, - sharedPluginData, - Frame boundaryRectangle, - style, - fills, - strokes, - strokeWeight, - strokeAlign, - cornerRadius, - FigmaConstraints constraints, - layoutAlign, - size, - horizontalPadding, - verticalPadding, - itemSpacing, - List children, - String UUID, - FigmaColor backgroundColor, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing}) - : super( - name: name, - isVisible: isVisible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - boundaryRectangle: boundaryRectangle, - style: style, - fills: fills, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - cornerRadius: cornerRadius, - constraints: constraints, - layoutAlign: layoutAlign, - size: size, - horizontalPadding: horizontalPadding, - verticalPadding: verticalPadding, - itemSpacing: itemSpacing, - children: children, - UUID: UUID, - backgroundColor: backgroundColor, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing) { - if (areAllVectors()) { - pbdfType = 'image'; - } else { - pbdfType = 'group'; - } - log = Logger(runtimeType.toString()); - } - - @override - FigmaNode createFigmaNode(Map json) => Group.fromJson(json); - factory Group.fromJson(Map json) => _$GroupFromJson(json); - @override - Map toJson() => _$GroupToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - if (areAllVectors()) { - imageReference = FigmaAssetProcessor().processImage(UUID); - - var tempPrototypeID = childrenHavePrototypeNode(); - if (tempPrototypeID != null) { - prototypeNodeUUID = tempPrototypeID; - } - - if (children != null && children.isNotEmpty) { - boundaryRectangle = fitFrame(); - } - - children.clear(); - - return Future.value( - InheritedBitmap(this, name, - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width)), - ); - } - var t = Future.value(TempGroupLayoutNode( - this, - currentContext, - name, - topLeftCorner: Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point( - boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width), - )); - // print(await t.then((value) => value.constraints)); - return t; - } - - bool areAllVectors() { - if (children == null) { - return false; - } - for (var child in children) { - if (child is! FigmaVector) { - return false; - } - if (child is FigmaText) { - return false; - } - } - return true; - } - - Frame fitFrame() { - var heights = []; - var widths = []; - for (var child in children) { - heights.add(child.boundaryRectangle.height); - widths.add(child.boundaryRectangle.width); - } - - if (heights.every((element) => element == heights[0]) && - widths.every((element) => element == widths[0])) { - return Frame( - height: heights[0], - width: widths[0], - x: boundaryRectangle.x, - y: boundaryRectangle.y, - ); - } else { - return boundaryRectangle; - } - } - - String childrenHavePrototypeNode() { - for (DesignNode child in children) { - if (child.prototypeNodeUUID != null) { - return child.prototypeNodeUUID; - } - } - return null; - } - - @override - String pbdfType = 'group'; -} diff --git a/lib/input/figma/entities/layers/group.g.dart b/lib/input/figma/entities/layers/group.g.dart deleted file mode 100644 index 456174a5..00000000 --- a/lib/input/figma/entities/layers/group.g.dart +++ /dev/null @@ -1,77 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'group.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Group _$GroupFromJson(Map json) { - return Group( - name: json['name'], - isVisible: json['visible'] ?? true, - type: json['type'], - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - strokes: json['strokes'], - strokeWeight: json['strokeWeight'], - strokeAlign: json['strokeAlign'], - cornerRadius: json['cornerRadius'], - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - layoutAlign: json['layoutAlign'], - size: json['size'], - horizontalPadding: json['horizontalPadding'], - verticalPadding: json['verticalPadding'], - itemSpacing: json['itemSpacing'], - children: (json['children'] as List) - ?.map((e) => - e == null ? null : FigmaNode.fromJson(e as Map)) - ?.toList(), - UUID: json['id'] as String, - backgroundColor: json['backgroundColor'] == null - ? null - : FigmaColor.fromJson(json['backgroundColor'] as Map), - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..isFlowHome = json['isFlowHome'] ?? false - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$GroupToJson(Group instance) => { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'children': instance.children, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'cornerRadius': instance.cornerRadius, - 'constraints': instance.constraints, - 'layoutAlign': instance.layoutAlign, - 'size': instance.size, - 'horizontalPadding': instance.horizontalPadding, - 'verticalPadding': instance.verticalPadding, - 'itemSpacing': instance.itemSpacing, - 'backgroundColor': instance.backgroundColor, - 'isFlowHome': instance.isFlowHome, - 'fills': instance.fillsList, - 'type': instance.type, - 'imageReference': instance.imageReference, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/instance.dart b/lib/input/figma/entities/layers/instance.dart deleted file mode 100644 index 41795859..00000000 --- a/lib/input/figma/entities/layers/instance.dart +++ /dev/null @@ -1,137 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/pb_shared_instance_design_node.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; -import 'package:parabeac_core/input/figma/entities/layers/frame.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/override_value.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -part 'instance.g.dart'; - -@JsonSerializable(nullable: true) -class Instance extends FigmaFrame - implements AbstractFigmaNodeFactory, PBSharedInstanceDesignNode { - @override - String type = 'INSTANCE'; - - @override - List parameters; - - @override - String symbolID; - - @override - List children; - Instance( - {name, - isVisible, - type, - pluginData, - sharedPluginData, - Frame boundaryRectangle, - style, - fills, - strokes, - strokeWeight, - strokeAlign, - cornerRadius, - FigmaConstraints constraints, - layoutAlign, - size, - horizontalPadding, - verticalPadding, - itemSpacing, - this.componentId, - List this.children, - this.parameters, - this.symbolID, - FigmaColor backgroundColor, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing}) - : super( - name: name, - isVisible: isVisible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - boundaryRectangle: boundaryRectangle, - style: style, - fills: fills, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - cornerRadius: cornerRadius, - constraints: constraints, - layoutAlign: layoutAlign, - size: size, - horizontalPadding: horizontalPadding, - verticalPadding: verticalPadding, - itemSpacing: itemSpacing, - children: children, - backgroundColor: backgroundColor, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing) { - pbdfType = 'symbol_instance'; - } - - String componentId; - - @override - FigmaNode createFigmaNode(Map json) => - Instance.fromJson(json); - factory Instance.fromJson(Map json) => - _$InstanceFromJson(json); - @override - Map toJson() => _$InstanceToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - /// TODO: Check if `sharedParamValues` exits and pass to it, default to emptu for now - var sym = PBSharedInstanceIntermediateNode(this, componentId, - sharedParamValues: [], - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width)); - return Future.value(sym); - } - - @override - String pbdfType = 'symbol_instance'; - - @override - Map AddMasterSymbolOverrideName(String overrideName, List children) { - // TODO: implement AddMasterSymbolOverrideName - throw UnimplementedError(); - } - - @override - String FindName(String uuid, List children, Type type) { - // TODO: implement FindName - throw UnimplementedError(); - } - - @override - Map extractParameter(String overrideName) { - // TODO: implement extractParameter - throw UnimplementedError(); - } - - @override - // TODO: implement overrideValues - List get overrideValues => throw UnimplementedError(); - - @override - // TODO: implement typeToAbbreviation - Map get typeToAbbreviation => throw UnimplementedError(); -} diff --git a/lib/input/figma/entities/layers/instance.g.dart b/lib/input/figma/entities/layers/instance.g.dart deleted file mode 100644 index e9ff65e3..00000000 --- a/lib/input/figma/entities/layers/instance.g.dart +++ /dev/null @@ -1,83 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'instance.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Instance _$InstanceFromJson(Map json) { - return Instance( - name: json['name'], - isVisible: json['visible'] ?? true, - type: json['type'], - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - strokes: json['strokes'], - strokeWeight: json['strokeWeight'], - strokeAlign: json['strokeAlign'], - cornerRadius: json['cornerRadius'], - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - layoutAlign: json['layoutAlign'], - size: json['size'], - horizontalPadding: json['horizontalPadding'], - verticalPadding: json['verticalPadding'], - itemSpacing: json['itemSpacing'], - componentId: json['componentId'] as String, - children: (json['children'] as List) - ?.map((e) => - e == null ? null : FigmaNode.fromJson(e as Map)) - ?.toList(), - parameters: json['parameters'] as List, - symbolID: json['symbolID'] as String, - backgroundColor: json['backgroundColor'] == null - ? null - : FigmaColor.fromJson(json['backgroundColor'] as Map), - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..isFlowHome = json['isFlowHome'] ?? false - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$InstanceToJson(Instance instance) => { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'cornerRadius': instance.cornerRadius, - 'constraints': instance.constraints, - 'layoutAlign': instance.layoutAlign, - 'size': instance.size, - 'horizontalPadding': instance.horizontalPadding, - 'verticalPadding': instance.verticalPadding, - 'itemSpacing': instance.itemSpacing, - 'backgroundColor': instance.backgroundColor, - 'isFlowHome': instance.isFlowHome, - 'fills': instance.fillsList, - 'imageReference': instance.imageReference, - 'type': instance.type, - 'parameters': instance.parameters, - 'symbolID': instance.symbolID, - 'children': instance.children, - 'componentId': instance.componentId, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/line.dart b/lib/input/figma/entities/layers/line.dart deleted file mode 100644 index 1dda84b9..00000000 --- a/lib/input/figma/entities/layers/line.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'dart:math'; - -import 'figma_node.dart'; - -part 'line.g.dart'; - -@JsonSerializable(nullable: true) -class FigmaLine extends FigmaVector implements AbstractFigmaNodeFactory { - @override - String type = 'LINE'; - FigmaLine( - {String name, - bool visible, - String type, - pluginData, - sharedPluginData, - style, - layoutAlign, - FigmaConstraints constraints, - Frame boundaryRectangle, - size, - fills, - strokes, - strokeWeight, - strokeAlign, - styles, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing}) - : super( - name: name, - visible: visible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - style: style, - layoutAlign: layoutAlign, - constraints: constraints, - boundaryRectangle: boundaryRectangle, - size: size, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - styles: styles, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'image'; - } - - @override - FigmaNode createFigmaNode(Map json) => - FigmaLine.fromJson(json); - factory FigmaLine.fromJson(Map json) => - _$FigmaLineFromJson(json); - @override - Map toJson() => _$FigmaLineToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - return Future.value(InheritedContainer( - this, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point( - boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height, - ), - name, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width), - )); - } - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'image'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/figma/entities/layers/line.g.dart b/lib/input/figma/entities/layers/line.g.dart deleted file mode 100644 index 4d685a90..00000000 --- a/lib/input/figma/entities/layers/line.g.dart +++ /dev/null @@ -1,62 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'line.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaLine _$FigmaLineFromJson(Map json) { - return FigmaLine( - name: json['name'] as String, - type: json['type'] as String, - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - style: json['style'], - layoutAlign: json['layoutAlign'], - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - size: json['size'], - strokes: json['strokes'], - strokeWeight: json['strokeWeight'], - strokeAlign: json['strokeAlign'], - styles: json['styles'], - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..isVisible = json['visible'] as bool ?? true - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$FigmaLineToJson(FigmaLine instance) => { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'style': instance.style, - 'layoutAlign': instance.layoutAlign, - 'constraints': instance.constraints, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'size': instance.size, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'styles': instance.styles, - 'fills': instance.fillsList, - 'imageReference': instance.imageReference, - 'type': instance.type, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/rectangle.dart b/lib/input/figma/entities/layers/rectangle.dart deleted file mode 100644 index 76750558..00000000 --- a/lib/input/figma/entities/layers/rectangle.dart +++ /dev/null @@ -1,160 +0,0 @@ -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_border.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; -import 'package:parabeac_core/input/figma/helper/style_extractor.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'dart:math'; - -import 'figma_node.dart'; - -part 'rectangle.g.dart'; - -@JsonSerializable(nullable: true) -class FigmaRectangle extends FigmaVector - with PBColorMixin - implements AbstractFigmaNodeFactory { - @override - String type = 'RECTANGLE'; - FigmaRectangle( - {String name, - bool isVisible, - type, - pluginData, - sharedPluginData, - style, - layoutAlign, - FigmaConstraints constraints, - Frame boundaryRectangle, - size, - strokes, - strokeWeight, - strokeAlign, - styles, - this.cornerRadius, - this.rectangleCornerRadii, - this.points, - List fillsList, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing}) - : super( - name: name, - visible: isVisible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - style: style, - layoutAlign: layoutAlign, - constraints: constraints, - boundaryRectangle: boundaryRectangle, - size: size, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - styles: styles, - fillsList: fillsList, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'rectangle'; - var fillsMap = - (fillsList == null || fillsList.isEmpty) ? {} : fillsList.first; - if (fillsMap != null && fillsMap['type'] == 'IMAGE') { - pbdfType = 'image'; - } - } - - List points; - double cornerRadius; - - List rectangleCornerRadii; - - @override - FigmaNode createFigmaNode(Map json) { - var node = FigmaRectangle.fromJson(json); - node.style = StyleExtractor().getStyle(json); - return node; - } - - factory FigmaRectangle.fromJson(Map json) => - _$FigmaRectangleFromJson(json); - @override - Map toJson() => _$FigmaRectangleToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - var fillsMap = - (fillsList == null || fillsList.isEmpty) ? {} : fillsList.first; - if (fillsMap != null && fillsMap['type'] == 'IMAGE') { - imageReference = FigmaAssetProcessor().processImage(UUID); - - return Future.value(InheritedBitmap( - this, - name, - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width), - )); - } - PBBorder border; - for (var b in style?.borders?.reversed ?? []) { - if (b.isEnabled) { - border = b; - } - } - return Future.value(InheritedContainer( - this, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - name, - currentContext: currentContext, - isBackgroundVisible: - !fillsMap.containsKey('visible') || fillsMap['visible'], - borderInfo: { - 'borderRadius': (style != null && style.borderOptions != null) - ? cornerRadius - : null, - 'borderColorHex': style.borders != null && style.borders.isNotEmpty - ? toHex(style.borders[0].color) - : null - }, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width), - )); - } - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'rectangle'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/figma/entities/layers/rectangle.g.dart b/lib/input/figma/entities/layers/rectangle.g.dart deleted file mode 100644 index 055aa26e..00000000 --- a/lib/input/figma/entities/layers/rectangle.g.dart +++ /dev/null @@ -1,71 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'rectangle.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaRectangle _$FigmaRectangleFromJson(Map json) { - return FigmaRectangle( - name: json['name'] as String, - isVisible: json['visible'] as bool ?? true, - type: json['type'], - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - style: json['style'], - layoutAlign: json['layoutAlign'], - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - size: json['size'], - strokes: json['strokes'], - strokeWeight: json['strokeWeight'], - strokeAlign: json['strokeAlign'], - styles: json['styles'], - cornerRadius: (json['cornerRadius'] as num)?.toDouble(), - rectangleCornerRadii: (json['rectangleCornerRadii'] as List) - ?.map((e) => (e as num)?.toDouble()) - ?.toList(), - points: json['points'] as List, - fillsList: json['fills'] as List, - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$FigmaRectangleToJson(FigmaRectangle instance) => - { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'style': instance.style, - 'layoutAlign': instance.layoutAlign, - 'constraints': instance.constraints, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'size': instance.size, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'styles': instance.styles, - 'fills': instance.fillsList, - 'imageReference': instance.imageReference, - 'type': instance.type, - 'points': instance.points, - 'cornerRadius': instance.cornerRadius, - 'rectangleCornerRadii': instance.rectangleCornerRadii, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/regular_polygon.dart b/lib/input/figma/entities/layers/regular_polygon.dart deleted file mode 100644 index 45de8465..00000000 --- a/lib/input/figma/entities/layers/regular_polygon.dart +++ /dev/null @@ -1,107 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:json_annotation/json_annotation.dart'; - -import 'figma_node.dart'; - -part 'regular_polygon.g.dart'; - -@JsonSerializable(nullable: true) -class FigmaRegularPolygon extends FigmaVector - implements AbstractFigmaNodeFactory { - @override - String type = 'REGULAR_POLYGON'; - FigmaRegularPolygon({ - String name, - bool visible, - String type, - pluginData, - sharedPluginData, - style, - layoutAlign, - FigmaConstraints constraints, - Frame boundaryRectangle, - size, - fills, - strokes, - strokeWeight, - strokeAlign, - styles, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing, - }) : super( - name: name, - visible: visible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - style: style, - layoutAlign: layoutAlign, - constraints: constraints, - boundaryRectangle: boundaryRectangle, - size: size, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - styles: styles, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'polygon'; - } - - @override - FigmaNode createFigmaNode(Map json) => - FigmaRegularPolygon.fromJson(json); - factory FigmaRegularPolygon.fromJson(Map json) => - _$FigmaRegularPolygonFromJson(json); - @override - Map toJson() => _$FigmaRegularPolygonToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - imageReference = FigmaAssetProcessor().processImage(UUID); - - return Future.value(InheritedBitmap( - this, - name, - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width), - )); - } - - @override - String imageReference; - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'polygon'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/figma/entities/layers/regular_polygon.g.dart b/lib/input/figma/entities/layers/regular_polygon.g.dart deleted file mode 100644 index 80fdcf2c..00000000 --- a/lib/input/figma/entities/layers/regular_polygon.g.dart +++ /dev/null @@ -1,64 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'regular_polygon.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaRegularPolygon _$FigmaRegularPolygonFromJson(Map json) { - return FigmaRegularPolygon( - name: json['name'] as String, - type: json['type'] as String, - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - style: json['style'], - layoutAlign: json['layoutAlign'], - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - size: json['size'], - strokes: json['strokes'], - strokeWeight: json['strokeWeight'], - strokeAlign: json['strokeAlign'], - styles: json['styles'], - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..isVisible = json['visible'] as bool ?? true - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$FigmaRegularPolygonToJson( - FigmaRegularPolygon instance) => - { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'style': instance.style, - 'layoutAlign': instance.layoutAlign, - 'constraints': instance.constraints, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'size': instance.size, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'styles': instance.styles, - 'fills': instance.fillsList, - 'type': instance.type, - 'imageReference': instance.imageReference, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/slice.dart b/lib/input/figma/entities/layers/slice.dart deleted file mode 100644 index b52d0f5b..00000000 --- a/lib/input/figma/entities/layers/slice.dart +++ /dev/null @@ -1,98 +0,0 @@ -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'dart:math'; - -part 'slice.g.dart'; - -@JsonSerializable(nullable: true) - -///A slice is an invisible object with a bounding box, -///represented as dashed lines in the editor. -///Its purpose is to allow you to export a specific part of a document. -///Generally, the only thing you will do with a slice is to add an -///exportSettings and export its content via exportAsync. -class FigmaSlice extends FigmaNode implements FigmaNodeFactory { - @override - String type = 'SLICE'; - - String layoutAlign; - - FigmaConstraints constraints; - - @override - @JsonKey(name: 'absoluteBoundingBox') - var boundaryRectangle; - - var size; - - FigmaSlice({ - String name, - bool visible, - String type, - pluginData, - sharedPluginData, - this.layoutAlign, - this.constraints, - Frame this.boundaryRectangle, - this.size, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing, - }) : super( - name, - visible, - type, - pluginData, - sharedPluginData, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'image'; - } - - @override - FigmaNode createFigmaNode(Map json) => - FigmaSlice.fromJson(json); - factory FigmaSlice.fromJson(Map json) => - _$FigmaSliceFromJson(json); - @override - Map toJson() => _$FigmaSliceToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - return Future.value(InheritedContainer( - this, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - name, - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width), - )); - } - - @override - bool isVisible; - - @override - @JsonKey(ignore: true) - var style; - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'image'; -} diff --git a/lib/input/figma/entities/layers/slice.g.dart b/lib/input/figma/entities/layers/slice.g.dart deleted file mode 100644 index 1ec6997e..00000000 --- a/lib/input/figma/entities/layers/slice.g.dart +++ /dev/null @@ -1,49 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'slice.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaSlice _$FigmaSliceFromJson(Map json) { - return FigmaSlice( - name: json['name'] as String, - type: json['type'] as String, - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - layoutAlign: json['layoutAlign'] as String, - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - size: json['size'], - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..isVisible = json['visible'] as bool ?? true - ..pbdfType = json['pbdfType'] as String; -} - -Map _$FigmaSliceToJson(FigmaSlice instance) => - { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'type': instance.type, - 'layoutAlign': instance.layoutAlign, - 'constraints': instance.constraints, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'size': instance.size, - 'visible': instance.isVisible, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/star.dart b/lib/input/figma/entities/layers/star.dart deleted file mode 100644 index 56f8504c..00000000 --- a/lib/input/figma/entities/layers/star.dart +++ /dev/null @@ -1,103 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:json_annotation/json_annotation.dart'; - -import 'figma_node.dart'; - -part 'star.g.dart'; - -@JsonSerializable(nullable: true) -class FigmaStar extends FigmaVector implements AbstractFigmaNodeFactory { - @override - String type = 'STAR'; - FigmaStar({ - String name, - bool visible, - String type, - pluginData, - sharedPluginData, - style, - layoutAlign, - FigmaConstraints constraints, - Frame boundaryRectangle, - size, - fills, - strokes, - strokeWeight, - strokeAlign, - styles, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing, - }) : super( - name: name, - visible: visible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - style: style, - layoutAlign: layoutAlign, - constraints: constraints, - boundaryRectangle: boundaryRectangle, - size: size, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - styles: styles, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'star'; - } - - @override - FigmaNode createFigmaNode(Map json) => - FigmaStar.fromJson(json); - factory FigmaStar.fromJson(Map json) => - _$FigmaStarFromJson(json); - @override - Map toJson() => _$FigmaStarToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - imageReference = FigmaAssetProcessor().processImage(UUID); - return Future.value(InheritedBitmap( - this, - name, - currentContext: currentContext, - referenceImage: imageReference, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width), - )); - } - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'star'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/figma/entities/layers/star.g.dart b/lib/input/figma/entities/layers/star.g.dart deleted file mode 100644 index d248f259..00000000 --- a/lib/input/figma/entities/layers/star.g.dart +++ /dev/null @@ -1,62 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'star.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaStar _$FigmaStarFromJson(Map json) { - return FigmaStar( - name: json['name'] as String, - type: json['type'] as String, - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - style: json['style'], - layoutAlign: json['layoutAlign'], - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - size: json['size'], - strokes: json['strokes'], - strokeWeight: json['strokeWeight'], - strokeAlign: json['strokeAlign'], - styles: json['styles'], - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..isVisible = json['visible'] as bool ?? true - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$FigmaStarToJson(FigmaStar instance) => { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'style': instance.style, - 'layoutAlign': instance.layoutAlign, - 'constraints': instance.constraints, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'size': instance.size, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'styles': instance.styles, - 'fills': instance.fillsList, - 'imageReference': instance.imageReference, - 'type': instance.type, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/layers/text.dart b/lib/input/figma/entities/layers/text.dart deleted file mode 100644 index ee96c0cc..00000000 --- a/lib/input/figma/entities/layers/text.dart +++ /dev/null @@ -1,152 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/design_logic/text.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/vector.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_style.dart'; -import 'package:parabeac_core/input/figma/helper/style_extractor.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'dart:math'; - -import 'figma_node.dart'; - -part 'text.g.dart'; - -@JsonSerializable(nullable: true) -class FigmaText extends FigmaVector implements AbstractFigmaNodeFactory, Text { - @override - String type = 'TEXT'; - FigmaText( - {String name, - bool visible, - String type, - pluginData, - sharedPluginData, - FigmaStyle this.style, - layoutAlign, - FigmaConstraints constraints, - Frame boundaryRectangle, - size, - fills, - strokes, - strokeWeight, - strokeAlign, - styles, - this.content, - this.characterStyleOverrides, - this.styleOverrideTable, - String prototypeNodeUUID, - num transitionDuration, - String transitionEasing}) - : super( - name: name, - visible: visible, - type: type, - pluginData: pluginData, - sharedPluginData: sharedPluginData, - style: style, - layoutAlign: layoutAlign, - constraints: constraints, - boundaryRectangle: boundaryRectangle, - size: size, - strokes: strokes, - strokeWeight: strokeWeight, - strokeAlign: strokeAlign, - styles: styles, - prototypeNodeUUID: prototypeNodeUUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - ) { - pbdfType = 'text'; - } - - @override - @JsonKey(name: 'characters') - String content; - - @override - PBStyle style; - - List characterStyleOverrides; - - Map styleOverrideTable; - - @override - FigmaNode createFigmaNode(Map json) { - var node = FigmaText.fromJson(json); - node.style = StyleExtractor().getStyle(json); - return node; - } - - factory FigmaText.fromJson(Map json) => - _$FigmaTextFromJson(json); - @override - Map toJson() => _$FigmaTextToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - return Future.value(InheritedContainer( - this, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - name, - currentContext: currentContext, - isBackgroundVisible: style.backgroundColor != null, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width), - )..addChild( - InheritedText( - this, - name, - currentContext: currentContext, - ), - )); - } - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'text'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } - - @override - var attributedString; - - @override - var automaticallyDrawOnUnderlyingPath; - - @override - var dontSynchroniseWithSymbol; - - @override - var glyphBounds; - - @override - var lineSpacingBehaviour; - - @override - var textBehaviour; -} diff --git a/lib/input/figma/entities/layers/text.g.dart b/lib/input/figma/entities/layers/text.g.dart deleted file mode 100644 index 7a1c2c7b..00000000 --- a/lib/input/figma/entities/layers/text.g.dart +++ /dev/null @@ -1,86 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'text.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaText _$FigmaTextFromJson(Map json) { - return FigmaText( - name: json['name'] as String, - type: json['type'] as String, - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - style: json['style'] == null - ? null - : FigmaStyle.fromJson(json['style'] as Map), - layoutAlign: json['layoutAlign'], - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - size: json['size'], - strokes: json['strokes'], - strokeWeight: json['strokeWeight'], - strokeAlign: json['strokeAlign'], - styles: json['styles'], - content: json['characters'] as String, - characterStyleOverrides: (json['characterStyleOverrides'] as List) - ?.map((e) => (e as num)?.toDouble()) - ?.toList(), - styleOverrideTable: json['styleOverrideTable'] as Map, - prototypeNodeUUID: json['transitionNodeID'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - ) - ..UUID = json['id'] as String - ..isVisible = json['visible'] as bool ?? true - ..fillsList = json['fills'] as List - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String - ..attributedString = json['attributedString'] - ..automaticallyDrawOnUnderlyingPath = - json['automaticallyDrawOnUnderlyingPath'] - ..dontSynchroniseWithSymbol = json['dontSynchroniseWithSymbol'] - ..glyphBounds = json['glyphBounds'] - ..lineSpacingBehaviour = json['lineSpacingBehaviour'] - ..textBehaviour = json['textBehaviour']; -} - -Map _$FigmaTextToJson(FigmaText instance) => { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'layoutAlign': instance.layoutAlign, - 'constraints': instance.constraints, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'size': instance.size, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'styles': instance.styles, - 'fills': instance.fillsList, - 'imageReference': instance.imageReference, - 'type': instance.type, - 'characters': instance.content, - 'style': instance.style, - 'characterStyleOverrides': instance.characterStyleOverrides, - 'styleOverrideTable': instance.styleOverrideTable, - 'pbdfType': instance.pbdfType, - 'attributedString': instance.attributedString, - 'automaticallyDrawOnUnderlyingPath': - instance.automaticallyDrawOnUnderlyingPath, - 'dontSynchroniseWithSymbol': instance.dontSynchroniseWithSymbol, - 'glyphBounds': instance.glyphBounds, - 'lineSpacingBehaviour': instance.lineSpacingBehaviour, - 'textBehaviour': instance.textBehaviour, - }; diff --git a/lib/input/figma/entities/layers/vector.dart b/lib/input/figma/entities/layers/vector.dart deleted file mode 100644 index 3b15adca..00000000 --- a/lib/input/figma/entities/layers/vector.dart +++ /dev/null @@ -1,129 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/image.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/figma/entities/abstract_figma_node_factory.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_node.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_style.dart'; -import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; -import 'package:parabeac_core/input/helper/figma_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:json_annotation/json_annotation.dart'; - -import 'package:quick_log/quick_log.dart'; - -part 'vector.g.dart'; - -@JsonSerializable(nullable: true) -class FigmaVector extends FigmaNode implements FigmaNodeFactory, Image { - @JsonKey(ignore: true) - Logger log; - @override - PBStyle style; - - String layoutAlign; - - FigmaConstraints constraints; - - @override - @JsonKey(name: 'absoluteBoundingBox') - var boundaryRectangle; - - var size; - - var strokes; - - double strokeWeight; - - String strokeAlign; - - var styles; - @override - String type = 'VECTOR'; - - @JsonKey(name: 'fills') - List fillsList; - - FigmaVector({ - String name, - bool visible, - String type, - pluginData, - sharedPluginData, - FigmaStyle this.style, - this.layoutAlign, - this.constraints, - Frame this.boundaryRectangle, - this.size, - this.strokes, - this.strokeWeight, - this.strokeAlign, - this.styles, - this.fillsList, - String UUID, - num transitionDuration, - String transitionEasing, - String prototypeNodeUUID, - }) : super( - name, - visible, - type, - pluginData, - sharedPluginData, - UUID: UUID, - transitionDuration: transitionDuration, - transitionEasing: transitionEasing, - prototypeNodeUUID: prototypeNodeUUID, - ) { - pbdfType = 'vector'; - log = Logger(runtimeType.toString()); - } - - @override - FigmaNode createFigmaNode(Map json) => - FigmaVector.fromJson(json); - factory FigmaVector.fromJson(Map json) => - _$FigmaVectorFromJson(json); - @override - Map toJson() => _$FigmaVectorToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - imageReference = FigmaAssetProcessor().processImage(UUID); - - return Future.value(InheritedBitmap( - this, - name, - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertFigmaConstraintToPBDLConstraint(constraints), - boundaryRectangle.height, - boundaryRectangle.width), - )); - } - - @override - String imageReference; - - @override - Map toPBDF() => toJson(); - - @override - String pbdfType = 'vector'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/figma/entities/layers/vector.g.dart b/lib/input/figma/entities/layers/vector.g.dart deleted file mode 100644 index 1efb36a7..00000000 --- a/lib/input/figma/entities/layers/vector.g.dart +++ /dev/null @@ -1,65 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'vector.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaVector _$FigmaVectorFromJson(Map json) { - return FigmaVector( - name: json['name'] as String, - type: json['type'] as String, - pluginData: json['pluginData'], - sharedPluginData: json['sharedPluginData'], - style: json['style'] == null - ? null - : FigmaStyle.fromJson(json['style'] as Map), - layoutAlign: json['layoutAlign'] as String, - constraints: json['constraints'] == null - ? null - : FigmaConstraints.fromJson( - json['constraints'] as Map), - boundaryRectangle: json['absoluteBoundingBox'] == null - ? null - : Frame.fromJson(json['absoluteBoundingBox'] as Map), - size: json['size'], - strokes: json['strokes'], - strokeWeight: (json['strokeWeight'] as num)?.toDouble(), - strokeAlign: json['strokeAlign'] as String, - styles: json['styles'], - fillsList: json['fills'] as List, - UUID: json['id'] as String, - transitionDuration: json['transitionDuration'] as num, - transitionEasing: json['transitionEasing'] as String, - prototypeNodeUUID: json['transitionNodeID'] as String, - ) - ..isVisible = json['visible'] as bool ?? true - ..imageReference = json['imageReference'] as String - ..pbdfType = json['pbdfType'] as String; -} - -Map _$FigmaVectorToJson(FigmaVector instance) => - { - 'id': instance.UUID, - 'name': instance.name, - 'pluginData': instance.pluginData, - 'sharedPluginData': instance.sharedPluginData, - 'visible': instance.isVisible, - 'transitionNodeID': instance.prototypeNodeUUID, - 'transitionDuration': instance.transitionDuration, - 'transitionEasing': instance.transitionEasing, - 'style': instance.style, - 'layoutAlign': instance.layoutAlign, - 'constraints': instance.constraints, - 'absoluteBoundingBox': instance.boundaryRectangle, - 'size': instance.size, - 'strokes': instance.strokes, - 'strokeWeight': instance.strokeWeight, - 'strokeAlign': instance.strokeAlign, - 'styles': instance.styles, - 'type': instance.type, - 'fills': instance.fillsList, - 'imageReference': instance.imageReference, - 'pbdfType': instance.pbdfType, - }; diff --git a/lib/input/figma/entities/style/figma_border.dart b/lib/input/figma/entities/style/figma_border.dart deleted file mode 100644 index fd6f11a1..00000000 --- a/lib/input/figma/entities/style/figma_border.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:parabeac_core/design_logic/pb_border.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'figma_border.g.dart'; - -@JsonSerializable() -class FigmaBorder implements PBBorder { - @override - final bool isEnabled; - @override - final double fillType; - @override - final FigmaColor color; - @override - final double thickness; - - FigmaBorder({ - this.isEnabled, - this.fillType, - this.color, - this.thickness, - }); - - @override - Map toJson() => _$FigmaBorderToJson(this); - factory FigmaBorder.fromJson(Map json) => - _$FigmaBorderFromJson(json); -} diff --git a/lib/input/figma/entities/style/figma_border.g.dart b/lib/input/figma/entities/style/figma_border.g.dart deleted file mode 100644 index 3abb91dc..00000000 --- a/lib/input/figma/entities/style/figma_border.g.dart +++ /dev/null @@ -1,26 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'figma_border.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaBorder _$FigmaBorderFromJson(Map json) { - return FigmaBorder( - isEnabled: json['isEnabled'] as bool, - fillType: (json['fillType'] as num)?.toDouble(), - color: json['color'] == null - ? null - : FigmaColor.fromJson(json['color'] as Map), - thickness: (json['thickness'] as num)?.toDouble(), - ); -} - -Map _$FigmaBorderToJson(FigmaBorder instance) => - { - 'isEnabled': instance.isEnabled, - 'fillType': instance.fillType, - 'color': instance.color, - 'thickness': instance.thickness, - }; diff --git a/lib/input/figma/entities/style/figma_border_options.dart b/lib/input/figma/entities/style/figma_border_options.dart deleted file mode 100644 index a2526098..00000000 --- a/lib/input/figma/entities/style/figma_border_options.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:parabeac_core/design_logic/pb_border_options.dart'; - -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_border.dart'; - -part 'figma_border_options.g.dart'; - -@JsonSerializable() -class FigmaBorderOptions implements PBBorderOptions { - @override - List dashPattern; - - @override - bool isEnabled; - - @override - int lineCapStyle; - - @override - int lineJoinStyle; - - FigmaBorderOptions( - this.dashPattern, - this.isEnabled, - this.lineCapStyle, - this.lineJoinStyle, - ); - - @override - Map toJson() => _$FigmaBorderOptionsToJson(this); - - factory FigmaBorderOptions.fromJson(Map json) => - _$FigmaBorderOptionsFromJson(json); -} diff --git a/lib/input/figma/entities/style/figma_border_options.g.dart b/lib/input/figma/entities/style/figma_border_options.g.dart deleted file mode 100644 index 2e23ca16..00000000 --- a/lib/input/figma/entities/style/figma_border_options.g.dart +++ /dev/null @@ -1,24 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'figma_border_options.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaBorderOptions _$FigmaBorderOptionsFromJson(Map json) { - return FigmaBorderOptions( - json['dashPattern'] as List, - json['isEnabled'] as bool, - json['lineCapStyle'] as int, - json['lineJoinStyle'] as int, - ); -} - -Map _$FigmaBorderOptionsToJson(FigmaBorderOptions instance) => - { - 'dashPattern': instance.dashPattern, - 'isEnabled': instance.isEnabled, - 'lineCapStyle': instance.lineCapStyle, - 'lineJoinStyle': instance.lineJoinStyle, - }; diff --git a/lib/input/figma/entities/style/figma_color.dart b/lib/input/figma/entities/style/figma_color.dart deleted file mode 100644 index 3bb9c45c..00000000 --- a/lib/input/figma/entities/style/figma_color.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:parabeac_core/design_logic/color.dart'; - -import 'package:json_annotation/json_annotation.dart'; -part 'figma_color.g.dart'; - -@JsonSerializable() -class FigmaColor implements PBColor { - @override - @JsonKey(name: 'a') - double alpha; - - @override - @JsonKey(name: 'b') - double blue; - - @override - @JsonKey(name: 'g') - double green; - - @override - @JsonKey(name: 'r') - double red; - - FigmaColor({this.alpha, this.red, this.green, this.blue}); - - @override - Map toJson() => _$FigmaColorToJson(this); - - factory FigmaColor.fromJson(Map json) => - _$FigmaColorFromJson(json); -} diff --git a/lib/input/figma/entities/style/figma_color.g.dart b/lib/input/figma/entities/style/figma_color.g.dart deleted file mode 100644 index ef184de9..00000000 --- a/lib/input/figma/entities/style/figma_color.g.dart +++ /dev/null @@ -1,24 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'figma_color.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaColor _$FigmaColorFromJson(Map json) { - return FigmaColor( - alpha: (json['a'] as num)?.toDouble(), - red: (json['r'] as num)?.toDouble(), - green: (json['g'] as num)?.toDouble(), - blue: (json['b'] as num)?.toDouble(), - ); -} - -Map _$FigmaColorToJson(FigmaColor instance) => - { - 'a': instance.alpha, - 'b': instance.blue, - 'g': instance.green, - 'r': instance.red, - }; diff --git a/lib/input/figma/entities/style/figma_fill.dart b/lib/input/figma/entities/style/figma_fill.dart deleted file mode 100644 index 93a81946..00000000 --- a/lib/input/figma/entities/style/figma_fill.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:parabeac_core/design_logic/pb_fill.dart'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; -part 'figma_fill.g.dart'; - -@JsonSerializable() -class FigmaFill implements PBFill { - @override - PBColor color; - - @override - int fillType; - - FigmaFill(FigmaColor this.color, [this.isEnabled = true]); - - @override - bool isEnabled; - - @override - Map toJson() => _$FigmaFillToJson(this); - factory FigmaFill.fromJson(Map json) => - _$FigmaFillFromJson(json); -} diff --git a/lib/input/figma/entities/style/figma_fill.g.dart b/lib/input/figma/entities/style/figma_fill.g.dart deleted file mode 100644 index 1a7681b9..00000000 --- a/lib/input/figma/entities/style/figma_fill.g.dart +++ /dev/null @@ -1,22 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'figma_fill.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaFill _$FigmaFillFromJson(Map json) { - return FigmaFill( - json['color'] == null - ? null - : FigmaColor.fromJson(json['color'] as Map), - json['isEnabled'] as bool, - )..fillType = json['fillType'] as int; -} - -Map _$FigmaFillToJson(FigmaFill instance) => { - 'color': instance.color, - 'fillType': instance.fillType, - 'isEnabled': instance.isEnabled, - }; diff --git a/lib/input/figma/entities/style/figma_style.dart b/lib/input/figma/entities/style/figma_style.dart deleted file mode 100644 index 7b820a9a..00000000 --- a/lib/input/figma/entities/style/figma_style.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/pb_border_options.dart'; -import 'package:parabeac_core/design_logic/pb_fill.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/design_logic/pb_border.dart'; -import 'package:parabeac_core/design_logic/pb_text_style.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_border.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_border_options.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_fill.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_text_style.dart'; - -part 'figma_style.g.dart'; - -@JsonSerializable() -class FigmaStyle implements PBStyle { - @override - PBColor backgroundColor; - @override - List fills = []; - @override - List borders; - @override - PBTextStyle textStyle; - - FigmaStyle({ - FigmaColor this.backgroundColor, - List this.borders, - List this.fills, - FigmaTextStyle this.textStyle, - FigmaBorderOptions this.borderOptions, - }) { - if (fills == null) { - fills = []; - } - } - - @override - PBBorderOptions borderOptions; - - @override - Map toJson() => _$FigmaStyleToJson(this); - factory FigmaStyle.fromJson(Map json) => - _$FigmaStyleFromJson(json); - - @override - @JsonKey(ignore: true) - bool hasShadow; -} diff --git a/lib/input/figma/entities/style/figma_style.g.dart b/lib/input/figma/entities/style/figma_style.g.dart deleted file mode 100644 index bac904ff..00000000 --- a/lib/input/figma/entities/style/figma_style.g.dart +++ /dev/null @@ -1,39 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'figma_style.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaStyle _$FigmaStyleFromJson(Map json) { - return FigmaStyle( - backgroundColor: json['backgroundColor'] == null - ? null - : FigmaColor.fromJson(json['backgroundColor'] as Map), - borders: (json['borders'] as List) - ?.map((e) => - e == null ? null : FigmaBorder.fromJson(e as Map)) - ?.toList(), - fills: (json['fills'] as List) - ?.map((e) => - e == null ? null : FigmaFill.fromJson(e as Map)) - ?.toList(), - textStyle: json['textStyle'] == null - ? null - : FigmaTextStyle.fromJson(json['textStyle'] as Map), - borderOptions: json['borderOptions'] == null - ? null - : FigmaBorderOptions.fromJson( - json['borderOptions'] as Map), - ); -} - -Map _$FigmaStyleToJson(FigmaStyle instance) => - { - 'backgroundColor': instance.backgroundColor, - 'fills': instance.fills, - 'borders': instance.borders, - 'textStyle': instance.textStyle, - 'borderOptions': instance.borderOptions, - }; diff --git a/lib/input/figma/entities/style/figma_text_style.dart b/lib/input/figma/entities/style/figma_text_style.dart deleted file mode 100644 index ceb567dc..00000000 --- a/lib/input/figma/entities/style/figma_text_style.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/pb_font_descriptor.dart'; -import 'package:parabeac_core/design_logic/pb_paragraph_style.dart'; -import 'package:parabeac_core/design_logic/pb_text_style.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_paragraph_style.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color.dart'; - -part 'figma_text_style.g.dart'; - -@JsonSerializable() -class FigmaTextStyle implements PBTextStyle { - @override - PBColor fontColor; - - @override - String weight; - - @JsonKey(ignore: true) - @override - PBFontDescriptor fontDescriptor; - - @override - @JsonKey(ignore: true) - PBParagraphStyle paragraphStyle; - - FigmaTextStyle({ - FigmaColor this.fontColor, - this.fontDescriptor, - this.weight, - this.paragraphStyle, - }); - - @override - Map toJson() => _$FigmaTextStyleToJson(this); - factory FigmaTextStyle.fromJson(Map json) => - _$FigmaTextStyleFromJson(json); -} diff --git a/lib/input/figma/entities/style/figma_text_style.g.dart b/lib/input/figma/entities/style/figma_text_style.g.dart deleted file mode 100644 index d5097964..00000000 --- a/lib/input/figma/entities/style/figma_text_style.g.dart +++ /dev/null @@ -1,22 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'figma_text_style.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaTextStyle _$FigmaTextStyleFromJson(Map json) { - return FigmaTextStyle( - fontColor: json['fontColor'] == null - ? null - : FigmaColor.fromJson(json['fontColor'] as Map), - weight: json['weight'] as String, - ); -} - -Map _$FigmaTextStyleToJson(FigmaTextStyle instance) => - { - 'fontColor': instance.fontColor, - 'weight': instance.weight, - }; diff --git a/lib/input/figma/helper/api_call_service.dart b/lib/input/figma/helper/api_call_service.dart deleted file mode 100644 index f820b6a6..00000000 --- a/lib/input/figma/helper/api_call_service.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'dart:convert'; -import 'dart:async'; -import 'dart:io'; -import 'package:http2/http2.dart'; -import 'package:quick_log/quick_log.dart'; - -import 'api_exceptions.dart'; - -class APICallService { - APICallService(); - static var log = Logger('API Call Service'); - - /// Makes a GET call to figma using `url` and `token` - static Future makeAPICall(String url, String token) async { - var response; - var uri = Uri.parse(url); - - /// The following request must be done using http2. The reason is - /// that the Figma API enforces http2, so using regular http will - /// not work. - try { - var transport = ClientTransportConnection.viaSocket( - await SecureSocket.connect( - uri.host, - uri.port, - supportedProtocols: ['h2'], - ), - ); - - var stream = transport.makeRequest( - [ - Header.ascii(':method', 'GET'), - Header.ascii( - ':path', uri.path + (uri.query.isEmpty ? '' : '?${uri.query}')), - Header.ascii(':scheme', uri.scheme), - Header.ascii(':authority', uri.host), - Header.ascii('x-figma-token', token), - ], - endStream: true, - ); - - final buffer = StringBuffer(); - await for (var message in stream.incomingMessages) { - if (message is HeadersStreamMessage) { - for (var header in message.headers) { - var name = utf8.decode(header.name); - var value = utf8.decode(header.value); - // print('Header: $name: $value'); - if (name == ':status') { - _returnResponse(int.parse(value)); - break; - } - } - } else if (message is DataStreamMessage) { - // Use [message.bytes] (but respect 'content-encoding' header) - buffer.write(utf8.decode(message.bytes)); - } - } - await transport.finish(); - var map = buffer.toString(); - response = json.decode(map); - return response; - } catch (e) { - print(e); - } - } - - static dynamic _returnResponse(int status) { - switch (status) { - case 200: - // TODO: Only print when verbose flag is active - // log.debug('API call went successfully : ${status}'); - break; - case 400: - log.error('BadRequestException : $status'); - throw BadRequestException(); - break; - case 401: - case 403: - log.error('UnauthorizedException : $status'); - throw UnauthorisedException(); - break; - case 500: - default: - log.error( - 'Error occured while Communication with Server with StatusCode : $status'); - throw FetchDataException( - 'Error occured while Communication with Server with StatusCode : $status'); - break; - } - } -} diff --git a/lib/input/figma/helper/api_exceptions.dart b/lib/input/figma/helper/api_exceptions.dart deleted file mode 100644 index c6e69347..00000000 --- a/lib/input/figma/helper/api_exceptions.dart +++ /dev/null @@ -1,26 +0,0 @@ -class APIException implements Exception { - final _message; - final _prefix; - APIException([this._message, this._prefix]); - @override - String toString() { - return "$_prefix$_message"; - } -} - -class FetchDataException extends APIException { - FetchDataException([String message]) - : super(message, 'Error During Communication: '); -} - -class BadRequestException extends APIException { - BadRequestException([message]) : super(message, 'Invalid Request: '); -} - -class UnauthorisedException extends APIException { - UnauthorisedException([message]) : super(message, 'Unauthorised: '); -} - -class InvalidInputException extends APIException { - InvalidInputException([String message]) : super(message, 'Invalid Input: '); -} diff --git a/lib/input/figma/helper/figma_asset_processor.dart b/lib/input/figma/helper/figma_asset_processor.dart deleted file mode 100644 index 670a608f..00000000 --- a/lib/input/figma/helper/figma_asset_processor.dart +++ /dev/null @@ -1,135 +0,0 @@ -import 'dart:io'; -import 'package:path/path.dart' as p; - -import 'package:http/http.dart' as http; -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/input/figma/helper/api_call_service.dart'; -import 'package:parabeac_core/input/helper/asset_processing_service.dart'; -import 'package:quick_log/quick_log.dart'; - -class FigmaAssetProcessor extends AssetProcessingService { - FigmaAssetProcessor._internal(); - - static final FigmaAssetProcessor _instance = FigmaAssetProcessor._internal(); - - factory FigmaAssetProcessor() => _instance; - - final List _uuidQueue = []; - - List get uuidQueue => _uuidQueue; - - Logger log = Logger('Figma Image helper'); - - /// Adds [uuid] to queue to be processed as an image. - /// Returns the formatted name of the image reference. - @override - String processImage(String uuid) { - _uuidQueue.add(uuid); - return AssetProcessingService.getImageName(uuid); - } - - /// Adds [uuids] to queue to be processed as an image. - /// Does NOT return image names when finished. - void _addImagesToQueue(List uuids) => _uuidQueue.addAll(uuids); - - /// Creates separate API requests from `uuidQueue` to speed up - /// the image downloading process. - Future processImageQueue({bool writeAsFile = true}) async { - List> uuidLists; - if (_uuidQueue.length >= 8) { - // Split uuids into 8 lists to create separate API requests to figma - uuidLists = List.generate(8, (_) => []); - for (var i = 0; i < _uuidQueue.length; i++) { - uuidLists[i % 8].add(_uuidQueue[i]); - } - } else { - uuidLists = [_uuidQueue]; - } - - // Process images in separate queues - var futures = []; - for (var uuidList in uuidLists) { - futures.add(_processImages(uuidList, writeAsFile: writeAsFile)); - } - - // Wait for the images to complete writing process - await Future.wait(futures, eagerError: true); - } - - /// Downloads the image with the given `UUID` - /// and writes it to the `pngs` folder in the `outputPath`. - /// Returns true if the operation was successful. Returns false - /// otherwise. - Future _processImages(List uuids, - {bool writeAsFile = true}) async { - // Call Figma API to get Image link - return Future(() async { - List> uuidsChunks = _listToChunks(uuids, 50); - - for (var list in uuidsChunks) { - var response = await APICallService.makeAPICall( - 'https://api.figma.com/v1/images/${MainInfo().figmaProjectID}?ids=${list.join(',')}&use_absolute_bounds=true', - MainInfo().figmaKey); - - if (response != null && - response.containsKey('images') && - response['images'] != null && - response['images'].values.isNotEmpty) { - Map images = response['images']; - // Download the images - for (var entry in images.entries) { - if (entry?.value != null && entry?.value?.isNotEmpty) { - response = await http.get(entry.value).then((imageRes) async { - // Check if the request was successful - if (imageRes == null || imageRes.statusCode != 200) { - log.error('Image ${entry.key} was not processed correctly'); - } - - if (writeAsFile) { - var pngsPath = p.join(MainInfo().pngPath, - '${entry.key}.png'.replaceAll(':', '_')); - var file = File(pngsPath)..createSync(recursive: true); - file.writeAsBytesSync(imageRes.bodyBytes); - } else { - await super.uploadToStorage(imageRes.bodyBytes, entry.key); - } - // TODO: Only print out when verbose flag is active - // log.debug('File written to following path ${file.path}'); - }).catchError((e) { - MainInfo().sentry.captureException(exception: e); - log.error(e.toString()); - }); - } - } - return response; - } - } - }); - } - - @override - Future processRootElements(Map uuids) async { - _addImagesToQueue(uuids.keys.toList()); - await processImageQueue(writeAsFile: false); - } - - List _listToChunks(List currentList, int chuckSize) { - var temp = []; - var counter = 0; - // ignore: omit_local_variable_types - List> listOnChunks = - currentList.fold>>([], (newList, i) { - counter++; - if (temp.length < chuckSize) { - temp.add(i); - } - if (temp.length >= chuckSize || currentList.length == counter) { - var newValue = List.from(temp); - newList.add(newValue); - temp.clear(); - } - return newList; - }); - return listOnChunks; - } -} diff --git a/lib/input/figma/helper/figma_page.dart b/lib/input/figma/helper/figma_page.dart deleted file mode 100644 index 9a51ff0e..00000000 --- a/lib/input/figma/helper/figma_page.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:parabeac_core/input/helper/design_page.dart'; -import 'package:quick_log/quick_log.dart'; - -class FigmaPage extends DesignPage { - @override - var log = Logger('FigmaPage'); - FigmaPage(String name, String id) - : super( - name: name, - id: id, - ); -} diff --git a/lib/input/figma/helper/figma_project.dart b/lib/input/figma/helper/figma_project.dart deleted file mode 100644 index cefdcd9b..00000000 --- a/lib/input/figma/helper/figma_project.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/input/figma/entities/layers/canvas.dart'; -import 'package:parabeac_core/input/figma/helper/figma_page.dart'; -import 'package:parabeac_core/input/helper/design_project.dart'; -import 'package:quick_log/src/logger.dart'; - -import 'figma_screen.dart'; - -class FigmaProject extends DesignProject { - @override - bool debug; - - @override - Logger log = Logger('FigmaProject'); - - @override - String projectName; - - var figmaJson; - - FigmaPage rootScreen; - - FigmaProject( - this.projectName, - this.figmaJson, { - String id, - }) : super(id: id) { - pages.addAll(_setConventionalPages(figmaJson['document']['children'])); - } - - List _setConventionalPages(var canvasAndArtboards) { - var figmaPages = []; - for (var canvas in canvasAndArtboards) { - // Skip current canvas if its convert property is false - var pbdlPage = getPbdlPage(canvas['id']); - if (pbdlPage != null && !(pbdlPage['convert'] ?? true)) { - continue; - } - - var pg = FigmaPage(canvas['name'], canvas['id']); - - var node = Canvas.fromJson(canvas); - - for (var layer in node.children) { - // Skip current screen if its convert property is false - var pbdlScreen = getPbdlScreen(pbdlPage, layer.UUID); - if (pbdlScreen != null && !(pbdlScreen['convert'] ?? true)) { - continue; - } - if (layer.UUID == node.prototypeStartNodeID) { - layer.isFlowHome = true; - } - pg.addScreen(FigmaScreen( - layer, - layer.UUID, - layer.name, - )); - } - figmaPages.add(pg); - } - return figmaPages; - } -} diff --git a/lib/input/figma/helper/figma_screen.dart b/lib/input/figma/helper/figma_screen.dart deleted file mode 100644 index 034be25a..00000000 --- a/lib/input/figma/helper/figma_screen.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/helper/design_page.dart'; -import 'package:parabeac_core/input/helper/design_screen.dart'; - -class FigmaScreen extends DesignScreen { - FigmaScreen( - DesignNode root, - String id, - String name, - ) : super( - designNode: root, - id: id, - name: name, - ); -} diff --git a/lib/input/figma/helper/style_extractor.dart b/lib/input/figma/helper/style_extractor.dart deleted file mode 100644 index 463a3b07..00000000 --- a/lib/input/figma/helper/style_extractor.dart +++ /dev/null @@ -1,140 +0,0 @@ -import 'package:parabeac_core/design_logic/pb_paragraph_style.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_font_descriptor.dart'; -import 'package:parabeac_core/input/figma/entities/layers/figma_paragraph_style.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_border.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_border_options.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_color.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_fill.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_style.dart'; -import 'package:parabeac_core/input/figma/entities/style/figma_text_style.dart'; - -/// Helper class used to get and sort the styling of FigmaNodes -class StyleExtractor { - StyleExtractor(); - - PBStyle getStyle(Map json) { - if (json != null) { - var bgColor; - // Check if color exists in fills - if (json['fills'] != null && json['fills'].isNotEmpty) { - // Check if color should be visible - if (!json['fills'][0].containsKey('visible') || - !json['fills'][0]['visible']) { - bgColor = _getColor(null); - } else { - bgColor = _getColor(json['background'][0]['color']); - } - } else { - bgColor = _getColor(null); - } - - var textStyle; - if (json['style'] != null) { - textStyle = _getTextStyle(json); - } - - var borders = []; - - var strokes = json['strokes']; - - var borderOptions; - - var visible = strokes.isNotEmpty ? strokes[0]['visible'] : false; - - var figmaBorder = FigmaBorder( - isEnabled: visible ?? false, - fillType: strokes.isNotEmpty ? strokes[0]['opacity'] : 1.0, - color: strokes.isNotEmpty - ? _getColor(strokes[0]['color']) - : _getColor(null), - thickness: json['strokeWeight'], - ); - - var tempVisible = strokes.isNotEmpty ? strokes[0]['visible'] : false; - - borderOptions = FigmaBorderOptions( - json['strokeDashes'], - tempVisible ?? false, - json['strokeCap'], - json['strokeJoin'], - ); - - borders.add(figmaBorder); - - var fills = []; - - var fill = FigmaFill( - _getColor(json['fills'].isNotEmpty ? json['fills'][0]['color'] : null), - ); - - fills.add(fill); - - return FigmaStyle( - backgroundColor: bgColor, - borders: borders, - textStyle: textStyle, - borderOptions: borderOptions, - fills: fills, - ); - } else { - return null; - } - } - - FigmaTextStyle _getTextStyle(Map json) { - var fontColor = json['fills'] != null - ? _getColor(json['fills'][0]['color']) - : _getColor(null); - var fontDescriptor = _getFontDescriptor(json['style']); - var alignment = _getAlignment(json['style']['textAlignHorizontal']); - - return FigmaTextStyle( - fontColor: fontColor, - fontDescriptor: fontDescriptor, - weight: '${json['style']['fontWeight']}', - paragraphStyle: FigmaParagraphStyle(alignment: alignment.index), - ); - } - - ALIGNMENT _getAlignment(String align) { - switch (align) { - case 'RIGHT': - return ALIGNMENT.RIGHT; - break; - case 'JUSTIFIED': - return ALIGNMENT.JUSTIFY; - break; - case 'CENTER': - return ALIGNMENT.CENTER; - break; - case 'LEFT': - default: - return ALIGNMENT.LEFT; - } - } - - FigmaFontDescriptor _getFontDescriptor(Map json) { - return FigmaFontDescriptor( - json['fontFamily'], - json['fontSize'], - json, - 'w' + (json['fontWeight'].toString() ?? '100'), - json.containsKey('italic') && json['italic'] ? 'italic' : 'normal', - json['letterSpacing'], - ); - } - - FigmaColor _getColor(Map json) { - if (json != null && json.isNotEmpty) { - return FigmaColor( - alpha: json['a'], - blue: json['b'], - green: json['g'], - red: json['r'], - ); - } else { - return null; - } - } -} diff --git a/lib/input/helper/asset_processing_service.dart b/lib/input/helper/asset_processing_service.dart deleted file mode 100644 index e121c01a..00000000 --- a/lib/input/helper/asset_processing_service.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; - -abstract class AssetProcessingService { - dynamic processImage(String uuid); - - Future processRootElements(Map uuids); - - AzureAssetService aaService = AzureAssetService(); - - static String getImageName(String uuid) => - ('images/' + uuid + '.png').replaceAll(':', '_'); - - Future uploadToStorage(Uint8List img, String name) async { - if (Platform.environment.containsKey(AzureAssetService.KEY_NAME) && - aaService.projectUUID != null) { - // Upload image to storage - - var cont = await aaService.createContainer( - aaService.projectUUID, - img, - ); - var blob = await aaService.putBlob( - aaService.projectUUID, - '$name.png', - img, - ); - await cont.stream.drain(); - await blob.stream.drain(); - } - } -} diff --git a/lib/input/helper/azure_asset_service.dart b/lib/input/helper/azure_asset_service.dart deleted file mode 100644 index 6a8c3d17..00000000 --- a/lib/input/helper/azure_asset_service.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:http/http.dart' as http; -import 'package:azblob/azblob.dart'; - -class AzureAssetService { - AzureAssetService._internal(); - - static final AzureAssetService _instance = AzureAssetService._internal(); - - factory AzureAssetService() => _instance; - - String _projectUUID; - - set projectUUID(String UUID) => _projectUUID = UUID; - - String get projectUUID => _projectUUID.toLowerCase(); - - static const KEY_NAME = 'STORAGE_CONNECTION_STRING'; - - String getImageURI(String imageName) => getContainerUri() + '/$imageName'; - - String getContainerUri() { - if (Platform.environment.containsKey(KEY_NAME) && projectUUID != null) { - var storageStringList = Platform.environment[KEY_NAME].split(';'); - var protocol = storageStringList[0].split('=')[1]; - var accName = storageStringList[1].split('=')[1]; - var suffix = storageStringList.last.split('=')[1]; - return '$protocol://$accName.blob.$suffix/$projectUUID'; - } - return ''; - } - - Future _putRequestBlob( - String path, Uint8List bodyBytes, - {Map queryParams}) async { - var storage = AzureStorage.parse(Platform.environment[KEY_NAME]); - var uri, headers; - // Request - if (queryParams == null) { - uri = storage.uri(path: '$path'); - headers = {'x-ms-blob-type': 'BlockBlob'}; - } else { - uri = storage.uri(path: '$path', queryParameters: queryParams); - } - - var request = http.Request('PUT', uri); - if (headers != null) { - request.headers.addAll(headers); - } - request.bodyBytes = bodyBytes; - storage.sign(request); - - var res = await request.send(); - return res; - } - - Future createContainer( - String container, Uint8List bodyBytes) async => - await _putRequestBlob('/$container', bodyBytes, - queryParams: {'restype': 'container'}); - - Future putBlob( - String container, String filename, Uint8List bodyBytes) async => - await _putRequestBlob('/$container/$filename', bodyBytes); - - Future downloadImage(String uuid) async { - var storage = AzureStorage.parse(Platform.environment[KEY_NAME]); - var uri = storage.uri(path: '/$projectUUID/$uuid.png'); - - var request = http.Request('GET', uri); - storage.sign(request); - - var res = await request.send(); - return await res.stream.toBytes(); - } -} diff --git a/lib/input/helper/design_page.dart b/lib/input/helper/design_page.dart deleted file mode 100644 index 86e6d848..00000000 --- a/lib/input/helper/design_page.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:parabeac_core/design_logic/abstract_design_node_factory.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:quick_log/quick_log.dart'; -import 'design_screen.dart'; - -class DesignPage implements DesignNodeFactory { - var log = Logger('DesignPage'); - - String id; - String imageURI; - String name; - bool convert = true; - List screens = []; - - DesignPage({ - this.name, - this.id, - }) { - screens = []; - } - - void addScreen(DesignScreen item) { - screens.add(item); - } - - List getPageItems() { - log.info('We encountered a page that has ${screens.length} page items.'); - return screens; - } - - /// Parabeac Design File - Map toPBDF() { - var result = {}; - result['pbdfType'] = pbdfType; - result['id'] = id; - result['name'] = name; - result['convert'] = convert; - - var tempScreens = []; - for (var screen in screens) { - tempScreens.add(screen.toPBDF()); - } - result['screens'] = tempScreens; - return result; - } - - @override - String pbdfType = 'design_page'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - factory DesignPage.fromPBDF(Map json) { - var page = DesignPage(name: json['name'], id: json['id']); - if (json.containsKey('screens')) { - (json['screens'] as List)?.forEach((value) { - if (value != null && (value['convert'] ?? true)) { - page.screens - .add(DesignScreen.fromPBDF(value as Map)); - } - }); - } - return page; - } -} diff --git a/lib/input/helper/design_project.dart b/lib/input/helper/design_project.dart deleted file mode 100644 index 03d17f0f..00000000 --- a/lib/input/helper/design_project.dart +++ /dev/null @@ -1,90 +0,0 @@ -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/abstract_design_node_factory.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/helper/design_page.dart'; - -import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; - -class DesignProject implements DesignNodeFactory { - String projectName; - bool debug = false; - String id; - @override - String pbdfType = 'project'; - - DesignProject({ - this.projectName, - this.id, - }); - - List pages = []; - List miscPages = []; - List sharedStyles = []; - - /// Parabeac Design File - Map toPBDF() { - Map result = {}; - result['projectName'] = projectName; - result['pbdfType'] = pbdfType; - result['id'] = id; - - var tmpPages = []; - var tmpMiscPages = []; - for (var page in pages) { - tmpPages.add(page.toPBDF()); - } - for (var page in miscPages) { - tmpMiscPages.add(page.toPBDF()); - } - - for (var sharedStyle in sharedStyles) { - result.addAll(sharedStyle.toJson()); - } - - result['pages'] = tmpPages; - result['miscPages'] = tmpMiscPages; - - return result; - } - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - factory DesignProject.fromPBDF(Map json) { - var project = - DesignProject(projectName: json['projectName'], id: json['id']); - if (json.containsKey('pages')) { - (json['pages'] as List)?.forEach((value) { - if (value != null) { - project.pages.add(DesignPage.fromPBDF(value as Map)); - } - }); - } - return project; - } - - /// Returns a [Map] that represents the PBDL page with ID `pageId`, - /// or `null` if not found. - Map getPbdlPage(String pageId) { - if (MainInfo().pbdf != null) { - List pages = MainInfo().pbdf['pages']; - return pages.singleWhere((element) => element['id'] == pageId, - orElse: () => null); - } - return null; - } - - /// Returns a [Map] that represents the PBDL screen with ID `screenId` - /// inside `pbdlPage`'s screens property. - Map getPbdlScreen(Map pbdlPage, String screenId) { - if (MainInfo().pbdf != null) { - List screens = pbdlPage['screens']; - return screens.singleWhere((element) => element['id'] == screenId, - orElse: () => null); - } - return null; - } -} diff --git a/lib/input/helper/design_screen.dart b/lib/input/helper/design_screen.dart deleted file mode 100644 index 050350bc..00000000 --- a/lib/input/helper/design_screen.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:parabeac_core/design_logic/abstract_design_node_factory.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; - -class DesignScreen implements DesignNodeFactory { - String id; - String name; - bool convert = true; - String imageURI; - String type; - DesignNode designNode; - - // Do we still need this? - // DesignPage parentPage; - - DesignScreen({ - DesignNode designNode, - this.id, - this.name, - this.type, - }) { - this.designNode = designNode; - } - - Map toPBDF() { - var result = {}; - if (type == 'symbolMaster') { - result['pbdfType'] = 'symbol_master'; - } else { - result['pbdfType'] = pbdfType; - } - result['id'] = id; - result['name'] = name; - result['convert'] = convert; - result['type'] = type; - result['designNode'] = designNode.toPBDF(); - result['azure_blob_uri'] = imageURI; - return result; - } - - @override - String pbdfType = 'screen'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - factory DesignScreen.fromPBDF(Map json) { - var screen = DesignScreen(name: json['name'], id: json['id']); - if (json.containsKey('designNode') && (json['convert'] ?? true)) { - screen.designNode = DesignNode.fromPBDF(json['designNode']); - } - return screen; - } - Map toJson() { - var result = {'azure_blob_uri': imageURI}; - result.addAll(designNode.toJson()); - return result; - } -} diff --git a/lib/input/sketch/entities/abstract_sketch_node_factory.dart b/lib/input/sketch/entities/abstract_sketch_node_factory.dart deleted file mode 100644 index 3a93a8a5..00000000 --- a/lib/input/sketch/entities/abstract_sketch_node_factory.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/artboard.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/bitmap.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/group.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/oval.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/page.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/polygon.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/rectangle.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/shape_group.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/shape_path.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/star.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/symbol_instance.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/symbol_master.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/sketch_text.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/triangle.dart'; - -///Abstract Factory for [SketchNode] -class AbstractSketchNodeFactory { - ///the key that gives the class type in the `SketchFiles`. - static final String SKETCH_CLASS_KEY = '_class'; - - static final List _sketchNodes = [ - Artboard(), - Bitmap(), - Group(), - Oval(), - Page(), - Polygon(), - Rectangle(), - ShapeGroup(), - ShapePath(), - SymbolInstance(), - SymbolMaster(), - SketchText(), - Star(), - Triangle() - ]; - - AbstractSketchNodeFactory(); - - static SketchNode getSketchNode(Map json) { - var className = json[SKETCH_CLASS_KEY]; - if (className != null) { - for (var sketchNode in _sketchNodes) { - if (sketchNode.CLASS_NAME == className) { - return sketchNode.createSketchNode(json); - } - } - } - return null; - } -} - -///Created another method for the factory because I could not access the regular -///factory constructor of each of the `SketchNode`s. Furthermore, the factory -///constructor creates less of an overhead (according to online docs). Regular -///method is just going to call the factory method. -abstract class SketchNodeFactory { - String CLASS_NAME; - SketchNode createSketchNode(Map json); -} diff --git a/lib/input/sketch/entities/documents/abstract_document.dart b/lib/input/sketch/entities/documents/abstract_document.dart deleted file mode 100644 index f5785a32..00000000 --- a/lib/input/sketch/entities/documents/abstract_document.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:parabeac_core/input/sketch/entities/objects/foreign_symbol.dart'; - -abstract class AbstractDocument { - final String CLASS_NAME = 'document'; - final dynamic UUID; - final dynamic assets; - final dynamic colorSpace; - final dynamic currentPageIndex; - final List foreignLayerStyles; - final List foreignSymbols; - final List foreignTextStyles; - final dynamic layerStyles; - final dynamic layerTextStyles; - final dynamic layerSymbols; - final List embeddedFontReferences; - final bool autoEmbedFonts; - final bool agreedToFontEmbedding; - - AbstractDocument( - this.UUID, - this.assets, - this.colorSpace, - this.currentPageIndex, - this.foreignLayerStyles, - this.foreignSymbols, - this.foreignTextStyles, - this.layerStyles, - this.layerTextStyles, - this.layerSymbols, - this.embeddedFontReferences, - this.autoEmbedFonts, - this.agreedToFontEmbedding); -} diff --git a/lib/input/sketch/entities/documents/document.dart b/lib/input/sketch/entities/documents/document.dart deleted file mode 100644 index cd37ae9e..00000000 --- a/lib/input/sketch/entities/documents/document.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/sketch/entities/documents/abstract_document.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/foreign_symbol.dart'; -part 'document.g.dart'; - -// title: Document -// description: The document entry in a Sketch file. -@JsonSerializable(nullable: true) -class Document extends AbstractDocument { - List pages; - - Document( - this.pages, - UUID, - assets, - colorSpace, - currentPageIndex, - List foreignLayerStyles, - List foreignSymbols, - List foreignTextStyles, - layerStyles, - layerTextStyles, - layerSymbols, - List embeddedFontReferences, - bool autoEmbedFonts, - bool agreedToFontEmbedding) - : super( - UUID, - assets, - colorSpace, - currentPageIndex, - foreignLayerStyles, - foreignSymbols, - foreignTextStyles, - layerStyles, - layerTextStyles, - layerSymbols, - embeddedFontReferences, - autoEmbedFonts, - agreedToFontEmbedding); - factory Document.fromJson(Map json) => - _$DocumentFromJson(json); - Map toJson() => _$DocumentToJson(this); -} diff --git a/lib/input/sketch/entities/documents/document.g.dart b/lib/input/sketch/entities/documents/document.g.dart deleted file mode 100644 index d6cb30f2..00000000 --- a/lib/input/sketch/entities/documents/document.g.dart +++ /dev/null @@ -1,47 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'document.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Document _$DocumentFromJson(Map json) { - return Document( - json['pages'] as List, - json['UUID'], - json['assets'], - json['colorSpace'], - json['currentPageIndex'], - json['foreignLayerStyles'] as List, - (json['foreignSymbols'] as List) - ?.map((e) => e == null - ? null - : ForeignSymbol.fromJson(e as Map)) - ?.toList(), - json['foreignTextStyles'] as List, - json['layerStyles'], - json['layerTextStyles'], - json['layerSymbols'], - json['embeddedFontReferences'] as List, - json['autoEmbedFonts'] as bool, - json['agreedToFontEmbedding'] as bool, - ); -} - -Map _$DocumentToJson(Document instance) => { - 'UUID': instance.UUID, - 'assets': instance.assets, - 'colorSpace': instance.colorSpace, - 'currentPageIndex': instance.currentPageIndex, - 'foreignLayerStyles': instance.foreignLayerStyles, - 'foreignSymbols': instance.foreignSymbols, - 'foreignTextStyles': instance.foreignTextStyles, - 'layerStyles': instance.layerStyles, - 'layerTextStyles': instance.layerTextStyles, - 'layerSymbols': instance.layerSymbols, - 'embeddedFontReferences': instance.embeddedFontReferences, - 'autoEmbedFonts': instance.autoEmbedFonts, - 'agreedToFontEmbedding': instance.agreedToFontEmbedding, - 'pages': instance.pages, - }; diff --git a/lib/input/sketch/entities/layers/abstract_group_layer.dart b/lib/input/sketch/entities/layers/abstract_group_layer.dart deleted file mode 100644 index 29902209..00000000 --- a/lib/input/sketch/entities/layers/abstract_group_layer.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/group_node.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; - -abstract class AbstractGroupLayer extends SketchNode implements GroupNode { - final bool hasClickThrough; - final dynamic groupLayout; - @override - final List children; - - AbstractGroupLayer( - this.hasClickThrough, - this.groupLayout, - this.children, - UUID, - booleanOperation, - exportOptions, - Frame boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - num rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition) - : super( - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation?.toDouble(), - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - Map toJson(); - - List getChildren() { - var result = []; - for (var child in children) { - result.add((child as DesignNode).toPBDF()); - } - return result; - } -} diff --git a/lib/input/sketch/entities/layers/abstract_layer.dart b/lib/input/sketch/entities/layers/abstract_layer.dart deleted file mode 100644 index 7a69313d..00000000 --- a/lib/input/sketch/entities/layers/abstract_layer.dart +++ /dev/null @@ -1,84 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -@JsonSerializable(nullable: true) -// title: Abstract Layer -// description: Abstract base schema for all layers -// type: object -abstract class SketchNode implements DesignNode { - @override - @JsonKey(name: 'do_objectID') - final String UUID; - final dynamic booleanOperation; - final dynamic exportOptions; - - ///`boundaryRectangle` is not final because its going to change, just because some node contain an offset. - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - Flow flow; - final bool isFixedToViewport; - final bool isFlippedHorizontal; - final bool isFlippedVertical; - final bool isLocked; - @override - final bool isVisible; - final dynamic layerListExpandedType; - @override - String name; - final bool nameIsFixed; - final int resizingConstraint; - final dynamic resizingType; - final num rotation; - final dynamic sharedStyleID; - final bool shouldBreakMaskChain; - final bool hasClippingMask; - final int clippingMaskMode; - final dynamic userInfo; - @override - final Style style; - final bool maintainScrollPosition; - - @override - set prototypeNodeUUID(String id) => flow?.destinationArtboardID ??= id; - @override - String get prototypeNodeUUID => flow?.destinationArtboardID; - - SketchNode( - this.UUID, - this.booleanOperation, - this.exportOptions, - Frame this.boundaryRectangle, - this.flow, - this.isFixedToViewport, - this.isFlippedHorizontal, - this.isFlippedVertical, - this.isLocked, - this.isVisible, - this.layerListExpandedType, - this.name, - this.nameIsFixed, - this.resizingConstraint, - this.resizingType, - this.rotation, - this.sharedStyleID, - this.shouldBreakMaskChain, - this.hasClippingMask, - this.clippingMaskMode, - this.userInfo, - this.style, - this.maintainScrollPosition); - - @override - Map toJson(); - factory SketchNode.fromJson(Map json) => - AbstractSketchNodeFactory.getSketchNode(json); - @override - Future interpretNode(PBContext currentContext); -} diff --git a/lib/input/sketch/entities/layers/abstract_shape_layer.dart b/lib/input/sketch/entities/layers/abstract_shape_layer.dart deleted file mode 100644 index ff9be9e1..00000000 --- a/lib/input/sketch/entities/layers/abstract_shape_layer.dart +++ /dev/null @@ -1,69 +0,0 @@ -// title: Abstract Shape Layer -// description: Abstract base layer for all shape layers -import 'package:parabeac_core/design_logic/design_shape.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; - -abstract class AbstractShapeLayer extends SketchNode implements DesignShape { - final bool edited; - final bool isClosed; - final dynamic pointRadiusBehaviour; - final List points; - - AbstractShapeLayer( - this.edited, - this.isClosed, - this.pointRadiusBehaviour, - this.points, - UUID, - booleanOperation, - exportOptions, - Frame boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - num rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition) - : super( - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation?.toDouble(), - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - @override - Map toJson(); -} diff --git a/lib/input/sketch/entities/layers/artboard.dart b/lib/input/sketch/entities/layers/artboard.dart deleted file mode 100644 index 3e1e9106..00000000 --- a/lib/input/sketch/entities/layers/artboard.dart +++ /dev/null @@ -1,221 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/artboard.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -part 'artboard.g.dart'; - -@JsonSerializable(nullable: true) -class Artboard extends AbstractGroupLayer - implements SketchNodeFactory, PBArtboard { - @override - @JsonKey(name: 'layers') - List children; - - @override - String CLASS_NAME = 'artboard'; - @override - @JsonKey(name: '_class') - String type; - final bool includeInCloudUpload; - final bool includeBackgroundColorInExport; - final dynamic horizontalRulerData; - final dynamic verticalRulerData; - final dynamic layout; - final dynamic grid; - - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - var backgroundColor; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - final bool hasBackgroundColor; - @override - final bool isFlowHome; - final bool resizesContent; - final dynamic presetDictionary; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - Artboard( - {this.includeInCloudUpload, - this.includeBackgroundColorInExport, - this.horizontalRulerData, - this.verticalRulerData, - this.layout, - this.grid, - Color this.backgroundColor, - this.hasBackgroundColor, - this.isFlowHome, - this.resizesContent, - this.presetDictionary, - hasClickThrough, - groupLayout, - List this.children, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition}) - : _isVisible = isVisible, - _style = style, - super( - hasClickThrough, - groupLayout, - (children as List), - UUID, - booleanOperation, - exportOptions, - boundaryRectangle as Frame, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - SketchNode createSketchNode(Map json) => - Artboard.fromJson(json); - factory Artboard.fromJson(Map json) => - _$ArtboardFromJson(json); - @override - Map toJson() => _$ArtboardToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - return Future.value(InheritedScaffold( - this, - currentContext: currentContext, - name: name, - isHomeScreen: isFlowHome, - )); - } - - @override - Map toPBDF() => { - // Change _class for type and layers for children and do_objectID for id - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'hasClickThrough': hasClickThrough, - 'groupLayout': groupLayout, - 'children': getChildren(), // changed it was layers - 'CLASS_NAME': CLASS_NAME, - 'type': type, // changed it was _class - 'includeInCloudUpload': includeInCloudUpload, - 'includeBackgroundColorInExport': includeBackgroundColorInExport, - 'horizontalRulerData': horizontalRulerData, - 'verticalRulerData': verticalRulerData, - 'layout': layout, - 'grid': grid, - 'absoluteBoundingBox': boundaryRectangle, // changed it was frame - 'backgroundColor': backgroundColor, - 'id': UUID, // changed it was do_objectID - 'hasBackgroundColor': hasBackgroundColor, - 'isFlowHome': isFlowHome, - 'resizesContent': resizesContent, - 'presetDictionary': presetDictionary, - 'visible': isVisible, // changed it was isVisible - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'artboard'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } - - @override - set isFlowHome(_isFlowHome) { - // TODO: implement isFlowHome - } -} diff --git a/lib/input/sketch/entities/layers/artboard.g.dart b/lib/input/sketch/entities/layers/artboard.g.dart deleted file mode 100644 index 186679ed..00000000 --- a/lib/input/sketch/entities/layers/artboard.g.dart +++ /dev/null @@ -1,107 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'artboard.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Artboard _$ArtboardFromJson(Map json) { - return Artboard( - includeInCloudUpload: json['includeInCloudUpload'] as bool, - includeBackgroundColorInExport: - json['includeBackgroundColorInExport'] as bool, - horizontalRulerData: json['horizontalRulerData'], - verticalRulerData: json['verticalRulerData'], - layout: json['layout'], - grid: json['grid'], - backgroundColor: json['backgroundColor'] == null - ? null - : Color.fromJson(json['backgroundColor'] as Map), - hasBackgroundColor: json['hasBackgroundColor'] as bool, - isFlowHome: json['isFlowHome'] as bool, - resizesContent: json['resizesContent'] as bool, - presetDictionary: json['presetDictionary'], - hasClickThrough: json['hasClickThrough'], - groupLayout: json['groupLayout'], - children: (json['layers'] as List) - ?.map((e) => - e == null ? null : SketchNode.fromJson(e as Map)) - ?.toList(), - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$ArtboardToJson(Artboard instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'hasClickThrough': instance.hasClickThrough, - 'groupLayout': instance.groupLayout, - 'layers': instance.children, - 'CLASS_NAME': instance.CLASS_NAME, - '_class': instance.type, - 'includeInCloudUpload': instance.includeInCloudUpload, - 'includeBackgroundColorInExport': instance.includeBackgroundColorInExport, - 'horizontalRulerData': instance.horizontalRulerData, - 'verticalRulerData': instance.verticalRulerData, - 'layout': instance.layout, - 'grid': instance.grid, - 'frame': instance.boundaryRectangle, - 'backgroundColor': instance.backgroundColor, - 'do_objectID': instance.UUID, - 'hasBackgroundColor': instance.hasBackgroundColor, - 'isFlowHome': instance.isFlowHome, - 'resizesContent': instance.resizesContent, - 'presetDictionary': instance.presetDictionary, - 'isVisible': instance.isVisible, - 'style': instance.style, - }; diff --git a/lib/input/sketch/entities/layers/bitmap.dart b/lib/input/sketch/entities/layers/bitmap.dart deleted file mode 100644 index 4542b319..00000000 --- a/lib/input/sketch/entities/layers/bitmap.dart +++ /dev/null @@ -1,200 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/image.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_deny_list_helper.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; - -part 'bitmap.g.dart'; - -@JsonSerializable(nullable: true) - -// title: Bitmap Layer -// description: Bitmap layers house a single image -class Bitmap extends SketchNode implements SketchNodeFactory, Image { - @override - String CLASS_NAME = 'bitmap'; - final bool fillReplacesImage; - final int intendedDPI; - final dynamic clippingMask; - - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - Bitmap({ - this.imageReference, - this.fillReplacesImage, - this.intendedDPI, - this.clippingMask, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - num rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition, - this.imageReferenceMap = const {}, - }) : _isVisible = isVisible, - _style = style, - super( - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation?.toDouble(), - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition) { - imageReference ??= imageReferenceMap['_ref']; - } - - @override - SketchNode createSketchNode(Map json) => - Bitmap.fromJson(json); - factory Bitmap.fromJson(Map json) => _$BitmapFromJson(json); - - @override - Map toJson() => _$BitmapToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - var intermediateNode; - intermediateNode = PBDenyListHelper().returnDenyListNodeIfExist(this); - if (intermediateNode != null) { - return intermediateNode; - } - intermediateNode = PBPluginListHelper().returnAllowListNodeIfExists(this); - if (intermediateNode != null) { - return intermediateNode; - } - return Future.value(InheritedBitmap(this, name, - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width))); - } - - @JsonKey(name: 'image') - Map imageReferenceMap; - - @override - @JsonKey(ignore: true) - String imageReference; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'CLASS_NAME': CLASS_NAME, - 'fillReplacesImage': fillReplacesImage, - 'intendedDPI': intendedDPI, - 'clippingMask': clippingMask, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'image': imageReferenceMap, - 'type': type, - 'visible': isVisible, - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'image'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/sketch/entities/layers/bitmap.g.dart b/lib/input/sketch/entities/layers/bitmap.g.dart deleted file mode 100644 index e46a98d7..00000000 --- a/lib/input/sketch/entities/layers/bitmap.g.dart +++ /dev/null @@ -1,81 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'bitmap.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Bitmap _$BitmapFromJson(Map json) { - return Bitmap( - fillReplacesImage: json['fillReplacesImage'] as bool, - intendedDPI: json['intendedDPI'] as int, - clippingMask: json['clippingMask'], - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'] as num, - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - imageReferenceMap: json['image'] as Map, - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$BitmapToJson(Bitmap instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'CLASS_NAME': instance.CLASS_NAME, - 'fillReplacesImage': instance.fillReplacesImage, - 'intendedDPI': instance.intendedDPI, - 'clippingMask': instance.clippingMask, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - 'image': instance.imageReferenceMap, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - }; diff --git a/lib/input/sketch/entities/layers/flow.dart b/lib/input/sketch/entities/layers/flow.dart deleted file mode 100644 index 119e6ea9..00000000 --- a/lib/input/sketch/entities/layers/flow.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'flow.g.dart'; - -@JsonSerializable(nullable: true) -class Flow { - @JsonKey(name: '_class') - final String classField; - String destinationArtboardID; - bool maintainScrollPosition; - dynamic animationType; - Flow({ - this.classField, - this.destinationArtboardID, - this.maintainScrollPosition, - this.animationType, - }); - factory Flow.fromJson(Map json) => _$FlowFromJson(json); - Map toJson() => _$FlowToJson(this); -} diff --git a/lib/input/sketch/entities/layers/flow.g.dart b/lib/input/sketch/entities/layers/flow.g.dart deleted file mode 100644 index 0402ca72..00000000 --- a/lib/input/sketch/entities/layers/flow.g.dart +++ /dev/null @@ -1,23 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'flow.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Flow _$FlowFromJson(Map json) { - return Flow( - classField: json['_class'] as String, - destinationArtboardID: json['destinationArtboardID'] as String, - maintainScrollPosition: json['maintainScrollPosition'] as bool, - animationType: json['animationType'], - ); -} - -Map _$FlowToJson(Flow instance) => { - '_class': instance.classField, - 'destinationArtboardID': instance.destinationArtboardID, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'animationType': instance.animationType, - }; diff --git a/lib/input/sketch/entities/layers/group.dart b/lib/input/sketch/entities/layers/group.dart deleted file mode 100644 index 46ac8fcc..00000000 --- a/lib/input/sketch/entities/layers/group.dart +++ /dev/null @@ -1,182 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; - -part 'group.g.dart'; - -@JsonSerializable(nullable: true) -class Group extends AbstractGroupLayer implements SketchNodeFactory { - @override - String CLASS_NAME = 'group'; - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_ref') - String imageReference; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - @override - @JsonKey(name: 'layers') - List children; - - Group( - {bool hasClickThrough, - groupLayout, - List this.children, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition}) - : _isVisible = isVisible, - _style = style, - super( - hasClickThrough, - groupLayout, - children, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - @override - SketchNode createSketchNode(Map json) => - _$GroupFromJson(json); - factory Group.fromJson(Map json) => _$GroupFromJson(json); - @override - Map toJson() => _$GroupToJson(this); - @override - Future interpretNode(PBContext currentContext) => - Future.value(TempGroupLayoutNode(this, currentContext, name, - topLeftCorner: - Point(boundaryRectangle.x, boundaryRectangle.y), - bottomRightCorner: Point( - boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width))); - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'hasClickThrough': hasClickThrough, - 'groupLayout': groupLayout, - 'CLASS_NAME': CLASS_NAME, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - '_ref': imageReference, - 'type': type, - 'visible': isVisible, - 'style': style, - 'children': getChildren(), - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'group'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/sketch/entities/layers/group.g.dart b/lib/input/sketch/entities/layers/group.g.dart deleted file mode 100644 index 63166ea2..00000000 --- a/lib/input/sketch/entities/layers/group.g.dart +++ /dev/null @@ -1,84 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'group.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Group _$GroupFromJson(Map json) { - return Group( - hasClickThrough: json['hasClickThrough'] as bool, - groupLayout: json['groupLayout'], - children: (json['layers'] as List) - ?.map((e) => - e == null ? null : SketchNode.fromJson(e as Map)) - ?.toList(), - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..imageReference = json['_ref'] as String - ..type = json['_class'] as String; -} - -Map _$GroupToJson(Group instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'hasClickThrough': instance.hasClickThrough, - 'groupLayout': instance.groupLayout, - 'CLASS_NAME': instance.CLASS_NAME, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_ref': instance.imageReference, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - 'layers': instance.children, - }; diff --git a/lib/input/sketch/entities/layers/oval.dart b/lib/input/sketch/entities/layers/oval.dart deleted file mode 100644 index 1b065851..00000000 --- a/lib/input/sketch/entities/layers/oval.dart +++ /dev/null @@ -1,171 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_shape_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_oval.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -part 'oval.g.dart'; - -// title: Oval Layer -// description: Oval layers are the result of adding an oval shape to the canvas -@JsonSerializable(nullable: true) -class Oval extends AbstractShapeLayer implements SketchNodeFactory { - @override - String CLASS_NAME = 'oval'; - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - Oval( - {bool edited, - bool isClosed, - pointRadiusBehaviour, - List points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition}) - : _isVisible = isVisible, - _style = style, - super( - edited, - isClosed, - pointRadiusBehaviour, - points, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - SketchNode createSketchNode(Map json) { - var oval = Oval.fromJson(json); - return oval; - } - - factory Oval.fromJson(Map json) => _$OvalFromJson(json); - @override - Map toJson() => _$OvalToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - var image = await SketchAssetProcessor() - .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); - - return Future.value(InheritedOval(this, name, - currentContext: currentContext, - image: image, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width))); - } - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'edited': edited, - 'isClosed': isClosed, - 'pointRadiusBehaviour': pointRadiusBehaviour, - 'points': points, - 'CLASS_NAME': CLASS_NAME, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'oval'; -} diff --git a/lib/input/sketch/entities/layers/oval.g.dart b/lib/input/sketch/entities/layers/oval.g.dart deleted file mode 100644 index 93c6ac1a..00000000 --- a/lib/input/sketch/entities/layers/oval.g.dart +++ /dev/null @@ -1,81 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'oval.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Oval _$OvalFromJson(Map json) { - return Oval( - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$OvalToJson(Oval instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'edited': instance.edited, - 'isClosed': instance.isClosed, - 'pointRadiusBehaviour': instance.pointRadiusBehaviour, - 'points': instance.points, - 'CLASS_NAME': instance.CLASS_NAME, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - }; diff --git a/lib/input/sketch/entities/layers/page.dart b/lib/input/sketch/entities/layers/page.dart deleted file mode 100644 index 3df29920..00000000 --- a/lib/input/sketch/entities/layers/page.dart +++ /dev/null @@ -1,182 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -part 'page.g.dart'; - -// title: Page Layer -// description: -// Page layers are the top level organisational abstraction within a document -@JsonSerializable(nullable: true) -class Page extends AbstractGroupLayer implements SketchNodeFactory { - @override - String CLASS_NAME = 'page'; - dynamic includeInCloudUpload; - dynamic horizontalRulerData; - dynamic verticalRulerData; - dynamic layout; - dynamic grid; - - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - @JsonKey(name: 'layers') - List children; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - Page( - {bool hasClickThrough, - groupLayout, - List this.children, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition}) - : _isVisible = isVisible, - _style = style, - super( - hasClickThrough, - groupLayout, - children, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - SketchNode createSketchNode(Map json) => Page.fromJson(json); - factory Page.fromJson(Map json) => _$PageFromJson(json); - @override - Map toJson() => _$PageToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - assert(false, 'We don\'t product pages as Intermediate Nodes.'); - return null; - } - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'hasClickThrough': hasClickThrough, - 'groupLayout': groupLayout, - 'CLASS_NAME': CLASS_NAME, - 'includeInCloudUpload': includeInCloudUpload, - 'horizontalRulerData': horizontalRulerData, - 'verticalRulerData': verticalRulerData, - 'layout': layout, - 'grid': grid, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'children': getChildren(), - 'visible': isVisible, - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'page'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/sketch/entities/layers/page.g.dart b/lib/input/sketch/entities/layers/page.g.dart deleted file mode 100644 index ca9f0078..00000000 --- a/lib/input/sketch/entities/layers/page.g.dart +++ /dev/null @@ -1,92 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'page.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Page _$PageFromJson(Map json) { - return Page( - hasClickThrough: json['hasClickThrough'] as bool, - groupLayout: json['groupLayout'], - children: (json['layers'] as List) - ?.map((e) => - e == null ? null : SketchNode.fromJson(e as Map)) - ?.toList(), - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..includeInCloudUpload = json['includeInCloudUpload'] - ..horizontalRulerData = json['horizontalRulerData'] - ..verticalRulerData = json['verticalRulerData'] - ..layout = json['layout'] - ..grid = json['grid'] - ..type = json['_class'] as String; -} - -Map _$PageToJson(Page instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'hasClickThrough': instance.hasClickThrough, - 'groupLayout': instance.groupLayout, - 'CLASS_NAME': instance.CLASS_NAME, - 'includeInCloudUpload': instance.includeInCloudUpload, - 'horizontalRulerData': instance.horizontalRulerData, - 'verticalRulerData': instance.verticalRulerData, - 'layout': instance.layout, - 'grid': instance.grid, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'layers': instance.children, - 'isVisible': instance.isVisible, - 'style': instance.style, - }; diff --git a/lib/input/sketch/entities/layers/polygon.dart b/lib/input/sketch/entities/layers/polygon.dart deleted file mode 100644 index 4005757d..00000000 --- a/lib/input/sketch/entities/layers/polygon.dart +++ /dev/null @@ -1,173 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/helper/asset_processing_service.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_shape_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_polygon.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -part 'polygon.g.dart'; - -// title: Polygon Layer -// description: Polygon layers are the result of adding an polygon shape to the canvas -@JsonSerializable(nullable: true) -class Polygon extends AbstractShapeLayer implements SketchNodeFactory { - @override - String CLASS_NAME = 'polygon'; - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - Polygon( - {bool edited, - bool isClosed, - pointRadiusBehaviour, - List points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition}) - : _isVisible = isVisible, - _style = style, - super( - edited, - isClosed, - pointRadiusBehaviour, - points, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - SketchNode createSketchNode(Map json) { - var polygon = Polygon.fromJson(json); - return polygon; - } - - factory Polygon.fromJson(Map json) => - _$PolygonFromJson(json); - @override - Map toJson() => _$PolygonToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - var image = await SketchAssetProcessor() - .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); - - return Future.value(InheritedPolygon(this, name, - currentContext: currentContext, - image: image, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width))); - } - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'edited': edited, - 'isClosed': isClosed, - 'pointRadiusBehaviour': pointRadiusBehaviour, - 'points': points, - 'CLASS_NAME': CLASS_NAME, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'polygon'; -} diff --git a/lib/input/sketch/entities/layers/polygon.g.dart b/lib/input/sketch/entities/layers/polygon.g.dart deleted file mode 100644 index c55fc02a..00000000 --- a/lib/input/sketch/entities/layers/polygon.g.dart +++ /dev/null @@ -1,81 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'polygon.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Polygon _$PolygonFromJson(Map json) { - return Polygon( - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$PolygonToJson(Polygon instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'edited': instance.edited, - 'isClosed': instance.isClosed, - 'pointRadiusBehaviour': instance.pointRadiusBehaviour, - 'points': instance.points, - 'CLASS_NAME': instance.CLASS_NAME, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - }; diff --git a/lib/input/sketch/entities/layers/rectangle.dart b/lib/input/sketch/entities/layers/rectangle.dart deleted file mode 100644 index 54e7408c..00000000 --- a/lib/input/sketch/entities/layers/rectangle.dart +++ /dev/null @@ -1,199 +0,0 @@ -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_shape_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/border.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; - -part 'rectangle.g.dart'; - -// title: Rectangle Layer -// description: -// Rectangle layers are the result of adding a rectangle shape to the canvas -@JsonSerializable(nullable: true) -class Rectangle extends AbstractShapeLayer - with PBColorMixin - implements SketchNodeFactory { - @override - String CLASS_NAME = 'rectangle'; - final double fixedRadius; - final bool hasConvertedToNewRoundCorners; - final bool needsConvertionToNewRoundCorners; - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - Rectangle( - {this.fixedRadius, - this.hasConvertedToNewRoundCorners, - this.needsConvertionToNewRoundCorners, - bool edited, - bool isClosed, - pointRadiusBehaviour, - List points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition}) - : _isVisible = isVisible, - _style = style, - super( - edited, - isClosed, - pointRadiusBehaviour, - points, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - @override - SketchNode createSketchNode(Map json) => - Rectangle.fromJson(json); - - factory Rectangle.fromJson(Map json) => - _$RectangleFromJson(json); - @override - Map toJson() => _$RectangleToJson(this); - - @override - Future interpretNode(PBContext currentContext) { - Border border; - for (var b in style.borders.reversed) { - if (b.isEnabled) { - border = b; - } - } - return Future.value( - InheritedContainer( - this, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - name, - currentContext: currentContext, - borderInfo: { - 'borderRadius': style.borderOptions.isEnabled - ? points[0]['cornerRadius'] - : null, - 'borderColorHex': border != null ? toHex(border.color) : null, - 'borderThickness': border != null ? border.thickness : null - }, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width)), - ); - } - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'edited': edited, - 'isClosed': isClosed, - 'pointRadiusBehaviour': pointRadiusBehaviour, - 'points': points, - 'CLASS_NAME': CLASS_NAME, - 'fixedRadius': fixedRadius, - 'hasConvertedToNewRoundCorners': hasConvertedToNewRoundCorners, - 'needsConvertionToNewRoundCorners': needsConvertionToNewRoundCorners, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'rectangle'; -} diff --git a/lib/input/sketch/entities/layers/rectangle.g.dart b/lib/input/sketch/entities/layers/rectangle.g.dart deleted file mode 100644 index 675a420c..00000000 --- a/lib/input/sketch/entities/layers/rectangle.g.dart +++ /dev/null @@ -1,90 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'rectangle.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Rectangle _$RectangleFromJson(Map json) { - return Rectangle( - fixedRadius: (json['fixedRadius'] as num)?.toDouble(), - hasConvertedToNewRoundCorners: - json['hasConvertedToNewRoundCorners'] as bool, - needsConvertionToNewRoundCorners: - json['needsConvertionToNewRoundCorners'] as bool, - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$RectangleToJson(Rectangle instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'edited': instance.edited, - 'isClosed': instance.isClosed, - 'pointRadiusBehaviour': instance.pointRadiusBehaviour, - 'points': instance.points, - 'CLASS_NAME': instance.CLASS_NAME, - 'fixedRadius': instance.fixedRadius, - 'hasConvertedToNewRoundCorners': instance.hasConvertedToNewRoundCorners, - 'needsConvertionToNewRoundCorners': - instance.needsConvertionToNewRoundCorners, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - }; diff --git a/lib/input/sketch/entities/layers/shape_group.dart b/lib/input/sketch/entities/layers/shape_group.dart deleted file mode 100644 index 1a95e670..00000000 --- a/lib/input/sketch/entities/layers/shape_group.dart +++ /dev/null @@ -1,187 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_group.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -part 'shape_group.g.dart'; - -// title: Shape Group Layer -// description: Shape groups layers group together multiple shape layers -@JsonSerializable(nullable: true) -class ShapeGroup extends AbstractGroupLayer implements SketchNodeFactory { - @override - String CLASS_NAME = 'shapeGroup'; - final dynamic windingRule; - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - @override - @JsonKey(name: 'layers') - List children; - - ShapeGroup( - {bool hasClickThrough, - groupLayout, - List this.children, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition, - this.windingRule}) - : _isVisible = isVisible, - _style = style, - super( - hasClickThrough, - groupLayout, - children, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - SketchNode createSketchNode(Map json) => - ShapeGroup.fromJson(json); - factory ShapeGroup.fromJson(Map json) => - _$ShapeGroupFromJson(json); - @override - Map toJson() => _$ShapeGroupToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - var image = await SketchAssetProcessor() - .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); - - return InheritedShapeGroup(this, name, - currentContext: currentContext, - image: image, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width)); - } - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'hasClickThrough': hasClickThrough, - 'groupLayout': groupLayout, - 'CLASS_NAME': CLASS_NAME, - 'windingRule': windingRule, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'children': getChildren(), - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'image'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/sketch/entities/layers/shape_group.g.dart b/lib/input/sketch/entities/layers/shape_group.g.dart deleted file mode 100644 index 45638bce..00000000 --- a/lib/input/sketch/entities/layers/shape_group.g.dart +++ /dev/null @@ -1,85 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'shape_group.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -ShapeGroup _$ShapeGroupFromJson(Map json) { - return ShapeGroup( - hasClickThrough: json['hasClickThrough'] as bool, - groupLayout: json['groupLayout'], - children: (json['layers'] as List) - ?.map((e) => - e == null ? null : SketchNode.fromJson(e as Map)) - ?.toList(), - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - windingRule: json['windingRule'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$ShapeGroupToJson(ShapeGroup instance) => - { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'hasClickThrough': instance.hasClickThrough, - 'groupLayout': instance.groupLayout, - 'CLASS_NAME': instance.CLASS_NAME, - 'windingRule': instance.windingRule, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - 'layers': instance.children, - }; diff --git a/lib/input/sketch/entities/layers/shape_path.dart b/lib/input/sketch/entities/layers/shape_path.dart deleted file mode 100644 index 19358fd8..00000000 --- a/lib/input/sketch/entities/layers/shape_path.dart +++ /dev/null @@ -1,170 +0,0 @@ -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_shape_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -part 'shape_path.g.dart'; - -// title: Shape Path Layer -// description: Shape path layers are the result of adding a vector layer -@JsonSerializable(nullable: true) -class ShapePath extends AbstractShapeLayer implements SketchNodeFactory { - @override - String CLASS_NAME = 'shapePath'; - - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @JsonKey(name: 'do_objectID') - @override - var UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - ShapePath( - {bool edited, - bool isClosed, - pointRadiusBehaviour, - List points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition}) - : _isVisible = isVisible, - _style = style, - super( - edited, - isClosed, - pointRadiusBehaviour, - points, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - SketchNode createSketchNode(Map json) => - ShapePath.fromJson(json); - factory ShapePath.fromJson(Map json) => - _$ShapePathFromJson(json); - @override - Map toJson() => _$ShapePathToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - var image = await SketchAssetProcessor() - .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); - - return Future.value(InheritedShapePath(this, name, - currentContext: currentContext, - image: image, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width))); - } - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'edited': edited, - 'isClosed': isClosed, - 'pointRadiusBehaviour': pointRadiusBehaviour, - 'points': points, - 'CLASS_NAME': CLASS_NAME, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'vector'; -} diff --git a/lib/input/sketch/entities/layers/shape_path.g.dart b/lib/input/sketch/entities/layers/shape_path.g.dart deleted file mode 100644 index 21d529ec..00000000 --- a/lib/input/sketch/entities/layers/shape_path.g.dart +++ /dev/null @@ -1,81 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'shape_path.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -ShapePath _$ShapePathFromJson(Map json) { - return ShapePath( - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$ShapePathToJson(ShapePath instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'edited': instance.edited, - 'isClosed': instance.isClosed, - 'pointRadiusBehaviour': instance.pointRadiusBehaviour, - 'points': instance.points, - 'CLASS_NAME': instance.CLASS_NAME, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - }; diff --git a/lib/input/sketch/entities/layers/sketch_text.dart b/lib/input/sketch/entities/layers/sketch_text.dart deleted file mode 100644 index f9ecbced..00000000 --- a/lib/input/sketch/entities/layers/sketch_text.dart +++ /dev/null @@ -1,233 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/text.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; -import 'package:uuid/uuid.dart'; - -part 'sketch_text.g.dart'; - -// title: Text Layer -// description: A text layer represents a discrete block or line of text -@JsonSerializable(nullable: true) -class SketchText extends SketchNode implements SketchNodeFactory, Text { - @override - String CLASS_NAME = 'text'; - - @override - final bool automaticallyDrawOnUnderlyingPath; - @override - final bool dontSynchroniseWithSymbol; - @override - final dynamic lineSpacingBehaviour; - @override - final dynamic textBehaviour; - @override - final dynamic glyphBounds; - - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - SketchText( - {this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - bool isFixedToViewport, - bool isFlippedHorizontal, - bool isFlippedVertical, - bool isLocked, - bool isVisible, - layerListExpandedType, - String name, - bool nameIsFixed, - int resizingConstraint, - resizingType, - double rotation, - sharedStyleID, - bool shouldBreakMaskChain, - bool hasClippingMask, - int clippingMaskMode, - userInfo, - Style style, - bool maintainScrollPosition, - this.attributedString, - this.automaticallyDrawOnUnderlyingPath, - this.dontSynchroniseWithSymbol, - this.lineSpacingBehaviour, - this.textBehaviour, - this.glyphBounds}) - : _isVisible = isVisible, - _style = style, - super( - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition) { - content = attributedString == null ? '' : attributedString['string']; - } - - @override - SketchNode createSketchNode(Map json) => - SketchText.fromJson(json); - factory SketchText.fromJson(Map json) => - _$SketchTextFromJson(json); - @override - Map toJson() => _$SketchTextToJson(this); - - @override - Future interpretNode(PBContext currentContext) => - Future.value(InjectedContainer( - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - Point(boundaryRectangle.x, boundaryRectangle.y), - name, - Uuid().v4(), - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width), - )..addChild( - InheritedText(this, name, currentContext: currentContext), - )); - - @override - @JsonKey(ignore: true) - String content; - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'CLASS_NAME': CLASS_NAME, - 'attributedString': attributedString, - 'automaticallyDrawOnUnderlyingPath': automaticallyDrawOnUnderlyingPath, - 'dontSynchroniseWithSymbol': dontSynchroniseWithSymbol, - 'lineSpacingBehaviour': lineSpacingBehaviour, - 'textBehaviour': textBehaviour, - 'glyphBounds': glyphBounds, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'text'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } - - @override - var attributedString; - - @override - set automaticallyDrawOnUnderlyingPath(_automaticallyDrawOnUnderlyingPath) { - // TODO: implement automaticallyDrawOnUnderlyingPath - } - - @override - set dontSynchroniseWithSymbol(_dontSynchroniseWithSymbol) { - // TODO: implement dontSynchroniseWithSymbol - } - - @override - set glyphBounds(_glyphBounds) { - // TODO: implement glyphBounds - } - - @override - set lineSpacingBehaviour(_lineSpacingBehaviour) { - // TODO: implement lineSpacingBehaviour - } - - @override - set textBehaviour(_textBehaviour) { - // TODO: implement textBehaviour - } -} diff --git a/lib/input/sketch/entities/layers/sketch_text.g.dart b/lib/input/sketch/entities/layers/sketch_text.g.dart deleted file mode 100644 index 6716475f..00000000 --- a/lib/input/sketch/entities/layers/sketch_text.g.dart +++ /dev/null @@ -1,88 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'sketch_text.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -SketchText _$SketchTextFromJson(Map json) { - return SketchText( - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'] as bool, - isFlippedHorizontal: json['isFlippedHorizontal'] as bool, - isFlippedVertical: json['isFlippedVertical'] as bool, - isLocked: json['isLocked'] as bool, - isVisible: json['isVisible'] as bool, - layerListExpandedType: json['layerListExpandedType'], - name: json['name'] as String, - nameIsFixed: json['nameIsFixed'] as bool, - resizingConstraint: json['resizingConstraint'] as int, - resizingType: json['resizingType'], - rotation: (json['rotation'] as num)?.toDouble(), - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'] as bool, - hasClippingMask: json['hasClippingMask'] as bool, - clippingMaskMode: json['clippingMaskMode'] as int, - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'] as bool, - attributedString: json['attributedString'], - automaticallyDrawOnUnderlyingPath: - json['automaticallyDrawOnUnderlyingPath'] as bool, - dontSynchroniseWithSymbol: json['dontSynchroniseWithSymbol'] as bool, - lineSpacingBehaviour: json['lineSpacingBehaviour'], - textBehaviour: json['textBehaviour'], - glyphBounds: json['glyphBounds'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$SketchTextToJson(SketchText instance) => - { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'CLASS_NAME': instance.CLASS_NAME, - 'automaticallyDrawOnUnderlyingPath': - instance.automaticallyDrawOnUnderlyingPath, - 'dontSynchroniseWithSymbol': instance.dontSynchroniseWithSymbol, - 'lineSpacingBehaviour': instance.lineSpacingBehaviour, - 'textBehaviour': instance.textBehaviour, - 'glyphBounds': instance.glyphBounds, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - 'attributedString': instance.attributedString, - }; diff --git a/lib/input/sketch/entities/layers/star.dart b/lib/input/sketch/entities/layers/star.dart deleted file mode 100644 index 0626191c..00000000 --- a/lib/input/sketch/entities/layers/star.dart +++ /dev/null @@ -1,174 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_shape_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_star.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -part 'star.g.dart'; - -// title: Star Layer -// description: Star layers are the result of adding an star shape to the canvas -@JsonSerializable(nullable: true) -class Star extends AbstractShapeLayer implements SketchNodeFactory { - @override - String CLASS_NAME = 'star'; - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - Star( - {bool edited, - bool isClosed, - pointRadiusBehaviour, - List points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition}) - : _isVisible = isVisible, - _style = style, - super( - edited, - isClosed, - pointRadiusBehaviour, - points, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - SketchNode createSketchNode(Map json) { - var star = Star.fromJson(json); - return star; - } - - factory Star.fromJson(Map json) => _$StarFromJson(json); - @override - Map toJson() => _$StarToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - var image = await SketchAssetProcessor() - .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); - - return Future.value(InheritedStar( - this, - name, - currentContext: currentContext, - image: image, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width), - )); - } - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'edited': edited, - 'isClosed': isClosed, - 'pointRadiusBehaviour': pointRadiusBehaviour, - 'points': points, - 'CLASS_NAME': CLASS_NAME, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'star'; -} diff --git a/lib/input/sketch/entities/layers/star.g.dart b/lib/input/sketch/entities/layers/star.g.dart deleted file mode 100644 index 8690c88d..00000000 --- a/lib/input/sketch/entities/layers/star.g.dart +++ /dev/null @@ -1,81 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'star.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Star _$StarFromJson(Map json) { - return Star( - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$StarToJson(Star instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'edited': instance.edited, - 'isClosed': instance.isClosed, - 'pointRadiusBehaviour': instance.pointRadiusBehaviour, - 'points': instance.points, - 'CLASS_NAME': instance.CLASS_NAME, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - }; diff --git a/lib/input/sketch/entities/layers/symbol_instance.dart b/lib/input/sketch/entities/layers/symbol_instance.dart deleted file mode 100644 index 60132147..00000000 --- a/lib/input/sketch/entities/layers/symbol_instance.dart +++ /dev/null @@ -1,215 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_shared_instance_design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/override_value.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -part 'symbol_instance.g.dart'; - -// title: Symbol Instance Layer -// description: Symbol instance layers represent an instance of a symbol master -@JsonSerializable(nullable: true) -class SymbolInstance extends SketchNode - with SymbolNodeMixin - implements SketchNodeFactory, PBSharedInstanceDesignNode { - @override - String CLASS_NAME = 'symbolInstance'; - @override - final List overrideValues; - final double scale; - @override - String symbolID; - final double verticalSpacing; - final double horizontalSpacing; - - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - SymbolInstance( - {this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - bool isFixedToViewport, - bool isFlippedHorizontal, - bool isFlippedVertical, - bool isLocked, - bool isVisible, - layerListExpandedType, - String name, - bool nameIsFixed, - resizingConstraint, - resizingType, - num rotation, - sharedStyleID, - bool shouldBreakMaskChain, - bool hasClippingMask, - int clippingMaskMode, - userInfo, - Style style, - bool maintainScrollPosition, - this.overrideValues, - this.scale, - this.symbolID, - this.verticalSpacing, - this.horizontalSpacing}) - : _isVisible = isVisible, - _style = style, - super( - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation?.toDouble(), - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - SketchNode createSketchNode(Map json) => - SymbolInstance.fromJson(json); - - factory SymbolInstance.fromJson(Map json) => - _$SymbolInstanceFromJson(json); - - @override - Map toJson() => _$SymbolInstanceToJson(this); - - ///Converting the [OverridableValue] into [PBSharedParameterValue] to be processed in intermediate phase. - List _extractParameters() { - var ovrNames = {}; - var sharedParameters = []; - for (var overrideValue in overrideValues) { - if (!ovrNames.contains(overrideValue.overrideName)) { - var properties = extractParameter(overrideValue.overrideName); - sharedParameters.add(PBSharedParameterValue( - properties['type'], - overrideValue.value, - properties['uuid'], - overrideValue.overrideName)); - ovrNames.add(overrideValue.overrideName); - } - } - - return sharedParameters; - } - - @override - Future interpretNode(PBContext currentContext) { - var sym = PBSharedInstanceIntermediateNode(this, symbolID, - sharedParamValues: _extractParameters(), - currentContext: currentContext, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width)); - return Future.value(sym); - } - - @override - List parameters; - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'CLASS_NAME': CLASS_NAME, - 'overrideValues': overrideValues, - 'scale': scale, - 'symbolID': symbolID, - 'verticalSpacing': verticalSpacing, - 'horizontalSpacing': horizontalSpacing, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'parameters': parameters, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'symbol_instance'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/sketch/entities/layers/symbol_instance.g.dart b/lib/input/sketch/entities/layers/symbol_instance.g.dart deleted file mode 100644 index 3a749fa2..00000000 --- a/lib/input/sketch/entities/layers/symbol_instance.g.dart +++ /dev/null @@ -1,90 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'symbol_instance.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -SymbolInstance _$SymbolInstanceFromJson(Map json) { - return SymbolInstance( - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'] as bool, - isFlippedHorizontal: json['isFlippedHorizontal'] as bool, - isFlippedVertical: json['isFlippedVertical'] as bool, - isLocked: json['isLocked'] as bool, - isVisible: json['isVisible'] as bool, - layerListExpandedType: json['layerListExpandedType'], - name: json['name'] as String, - nameIsFixed: json['nameIsFixed'] as bool, - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'] as num, - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'] as bool, - hasClippingMask: json['hasClippingMask'] as bool, - clippingMaskMode: json['clippingMaskMode'] as int, - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'] as bool, - overrideValues: (json['overrideValues'] as List) - ?.map((e) => e == null - ? null - : OverridableValue.fromJson(e as Map)) - ?.toList(), - scale: (json['scale'] as num)?.toDouble(), - symbolID: json['symbolID'] as String, - verticalSpacing: (json['verticalSpacing'] as num)?.toDouble(), - horizontalSpacing: (json['horizontalSpacing'] as num)?.toDouble(), - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String - ..parameters = json['parameters'] as List; -} - -Map _$SymbolInstanceToJson(SymbolInstance instance) => - { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'CLASS_NAME': instance.CLASS_NAME, - 'overrideValues': instance.overrideValues, - 'scale': instance.scale, - 'symbolID': instance.symbolID, - 'verticalSpacing': instance.verticalSpacing, - 'horizontalSpacing': instance.horizontalSpacing, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - 'parameters': instance.parameters, - }; diff --git a/lib/input/sketch/entities/layers/symbol_master.dart b/lib/input/sketch/entities/layers/symbol_master.dart deleted file mode 100644 index fc444cc1..00000000 --- a/lib/input/sketch/entities/layers/symbol_master.dart +++ /dev/null @@ -1,265 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/pb_shared_instance_design_node.dart'; -import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/override_property.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/override_value.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; -part 'symbol_master.g.dart'; - -// title: Symbol Master Layer -// description: A symbol master layer represents a reusable group of layers -@JsonSerializable(nullable: true) -class SymbolMaster extends AbstractGroupLayer - with SymbolNodeMixin - implements SketchNodeFactory, PBSharedInstanceDesignNode { - @override - String CLASS_NAME = 'symbolMaster'; - @override - var overrideValues; - final Color backgroundColor; - final bool hasBackgroundColor; - final dynamic horizontalRulerData; - final bool includeBackgroundColorInExport; - final bool includeInCloudUpload; - final bool isFlowHome; - final bool resizesContent; - final dynamic verticalRulerData; - final bool includeBackgroundColorInInstance; - @override - String symbolID; - final int changeIdentifier; - final bool allowsOverrides; - final List overrideProperties; - final dynamic presetDictionary; - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - - @override - @JsonKey(name: 'layers') - List children; - - SymbolMaster( - {bool hasClickThrough, - groupLayout, - List this.children, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition, - this.backgroundColor, - this.hasBackgroundColor, - this.horizontalRulerData, - this.includeBackgroundColorInExport, - this.includeInCloudUpload, - this.isFlowHome, - this.resizesContent, - this.verticalRulerData, - this.includeBackgroundColorInInstance, - this.symbolID, - this.changeIdentifier, - this.allowsOverrides, - this.overrideProperties, - this.presetDictionary}) - : _isVisible = isVisible, - _style = style, - super( - hasClickThrough, - groupLayout, - children, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition) { - if (name != null) { - this.name = name?.replaceAll(RegExp(r'[\s_\+]'), ''); - this.name = PBInputFormatter.removeFirstDigits(name); - } - } - - @override - List parameters; - - @override - SketchNode createSketchNode(Map json) => - SymbolMaster.fromJson(json); - factory SymbolMaster.fromJson(Map json) => - _$SymbolMasterFromJson(json); - @override - Map toJson() => _$SymbolMasterToJson(this); - - ///Converting the [OverridableProperty] into [PBSharedParameterProp] to be processed in intermediate phase. - List _extractParameters() { - var ovrNames = {}; - var sharedParameters = []; - for (var prop in overrideProperties) { - if (!ovrNames.contains(prop.overrideName)) { - var properties = AddMasterSymbolOverrideName(prop.overrideName, children); - sharedParameters.add(PBSharedParameterProp( - properties['name'], - properties['type'], - null, - prop.canOverride, - prop.overrideName, - properties['uuid'], - properties['default_value'])); - ovrNames.add(prop.overrideName); - } - } - return sharedParameters; - } - - @override - Future interpretNode(PBContext currentContext) { - var sym_master = PBSharedMasterNode( - this, - symbolID, - name, - Point(boundaryRectangle.x, boundaryRectangle.y), - Point(boundaryRectangle.x + boundaryRectangle.width, - boundaryRectangle.y + boundaryRectangle.height), - overridableProperties: _extractParameters(), - currentContext: currentContext, - ); - return Future.value(sym_master); - } - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'hasClickThrough': hasClickThrough, - 'groupLayout': groupLayout, - 'CLASS_NAME': CLASS_NAME, - 'backgroundColor': backgroundColor, - 'hasBackgroundColor': hasBackgroundColor, - 'horizontalRulerData': horizontalRulerData, - 'includeBackgroundColorInExport': includeBackgroundColorInExport, - 'includeInCloudUpload': includeInCloudUpload, - 'isFlowHome': isFlowHome, - 'resizesContent': resizesContent, - 'verticalRulerData': verticalRulerData, - 'includeBackgroundColorInInstance': includeBackgroundColorInInstance, - 'symbolID': symbolID, - 'changeIdentifier': changeIdentifier, - 'allowsOverrides': allowsOverrides, - 'overrideProperties': overrideProperties, - 'presetDictionary': presetDictionary, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'children': getChildren(), - 'parameters': parameters, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'symbol_master'; - - @override - DesignNode createDesignNode(Map json) { - // TODO: implement createDesignNode - throw UnimplementedError(); - } - - @override - DesignNode fromPBDF(Map json) { - // TODO: implement fromPBDF - throw UnimplementedError(); - } -} diff --git a/lib/input/sketch/entities/layers/symbol_master.g.dart b/lib/input/sketch/entities/layers/symbol_master.g.dart deleted file mode 100644 index bae59ab4..00000000 --- a/lib/input/sketch/entities/layers/symbol_master.g.dart +++ /dev/null @@ -1,128 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'symbol_master.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -SymbolMaster _$SymbolMasterFromJson(Map json) { - return SymbolMaster( - hasClickThrough: json['hasClickThrough'] as bool, - groupLayout: json['groupLayout'], - children: (json['layers'] as List) - ?.map((e) => - e == null ? null : SketchNode.fromJson(e as Map)) - ?.toList(), - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - backgroundColor: json['backgroundColor'] == null - ? null - : Color.fromJson(json['backgroundColor'] as Map), - hasBackgroundColor: json['hasBackgroundColor'] as bool, - horizontalRulerData: json['horizontalRulerData'], - includeBackgroundColorInExport: - json['includeBackgroundColorInExport'] as bool, - includeInCloudUpload: json['includeInCloudUpload'] as bool, - isFlowHome: json['isFlowHome'] as bool, - resizesContent: json['resizesContent'] as bool, - verticalRulerData: json['verticalRulerData'], - includeBackgroundColorInInstance: - json['includeBackgroundColorInInstance'] as bool, - symbolID: json['symbolID'] as String, - changeIdentifier: json['changeIdentifier'] as int, - allowsOverrides: json['allowsOverrides'] as bool, - overrideProperties: (json['overrideProperties'] as List) - ?.map((e) => e == null - ? null - : OverridableProperty.fromJson(e as Map)) - ?.toList(), - presetDictionary: json['presetDictionary'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..overrideValues = (json['overrideValues'] as List) - ?.map((e) => e == null - ? null - : OverridableValue.fromJson(e as Map)) - ?.toList() - ..type = json['_class'] as String - ..parameters = json['parameters'] as List; -} - -Map _$SymbolMasterToJson(SymbolMaster instance) => - { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'hasClickThrough': instance.hasClickThrough, - 'groupLayout': instance.groupLayout, - 'CLASS_NAME': instance.CLASS_NAME, - 'overrideValues': instance.overrideValues, - 'backgroundColor': instance.backgroundColor, - 'hasBackgroundColor': instance.hasBackgroundColor, - 'horizontalRulerData': instance.horizontalRulerData, - 'includeBackgroundColorInExport': instance.includeBackgroundColorInExport, - 'includeInCloudUpload': instance.includeInCloudUpload, - 'isFlowHome': instance.isFlowHome, - 'resizesContent': instance.resizesContent, - 'verticalRulerData': instance.verticalRulerData, - 'includeBackgroundColorInInstance': - instance.includeBackgroundColorInInstance, - 'symbolID': instance.symbolID, - 'changeIdentifier': instance.changeIdentifier, - 'allowsOverrides': instance.allowsOverrides, - 'overrideProperties': instance.overrideProperties, - 'presetDictionary': instance.presetDictionary, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - 'layers': instance.children, - 'parameters': instance.parameters, - }; diff --git a/lib/input/sketch/entities/layers/triangle.dart b/lib/input/sketch/entities/layers/triangle.dart deleted file mode 100644 index f1cfaf1b..00000000 --- a/lib/input/sketch/entities/layers/triangle.dart +++ /dev/null @@ -1,172 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/sketch/entities/abstract_sketch_node_factory.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_shape_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/flow.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/frame.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_constraint_to_pbdl.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_triangle.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; - -part 'triangle.g.dart'; - -// title: Triangle Layer -// description: Triangle layers are the result of adding an triangle shape to the canvas -@JsonSerializable(nullable: true) -class Triangle extends AbstractShapeLayer implements SketchNodeFactory { - @override - String CLASS_NAME = 'triangle'; - @override - @JsonKey(name: 'frame') - var boundaryRectangle; - - @override - @JsonKey(name: 'do_objectID') - String UUID; - - @override - @JsonKey(name: '_class') - String type; - - bool _isVisible; - - Style _style; - - @override - set isVisible(bool _isVisible) => this._isVisible = _isVisible; - - @override - bool get isVisible => _isVisible; - - @override - set style(_style) => this._style = _style; - - @override - Style get style => _style; - Triangle( - {bool edited, - bool isClosed, - pointRadiusBehaviour, - List points, - this.UUID, - booleanOperation, - exportOptions, - Frame this.boundaryRectangle, - Flow flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - Style style, - maintainScrollPosition}) - : _isVisible = isVisible, - _style = style, - super( - edited, - isClosed, - pointRadiusBehaviour, - points, - UUID, - booleanOperation, - exportOptions, - boundaryRectangle, - flow, - isFixedToViewport, - isFlippedHorizontal, - isFlippedVertical, - isLocked, - isVisible, - layerListExpandedType, - name, - nameIsFixed, - resizingConstraint, - resizingType, - rotation, - sharedStyleID, - shouldBreakMaskChain, - hasClippingMask, - clippingMaskMode, - userInfo, - style, - maintainScrollPosition); - - @override - SketchNode createSketchNode(Map json) { - var triangle = Triangle.fromJson(json); - return triangle; - } - - factory Triangle.fromJson(Map json) => - _$TriangleFromJson(json); - @override - Map toJson() => _$TriangleToJson(this); - - @override - Future interpretNode(PBContext currentContext) async { - var image = await SketchAssetProcessor() - .processImage(UUID, boundaryRectangle.width, boundaryRectangle.height); - - return Future.value(InheritedTriangle(this, name, - currentContext: currentContext, - image: image, - constraints: PBIntermediateConstraints.fromConstraints( - convertSketchConstraintToPBDLConstraint(resizingConstraint), - boundaryRectangle.height, - boundaryRectangle.width))); - } - - @override - Map toPBDF() => { - 'booleanOperation': booleanOperation, - 'exportOptions': exportOptions, - 'flow': flow, - 'isFixedToViewport': isFixedToViewport, - 'isFlippedHorizontal': isFlippedHorizontal, - 'isFlippedVertical': isFlippedVertical, - 'isLocked': isLocked, - 'layerListExpandedType': layerListExpandedType, - 'name': name, - 'nameIsFixed': nameIsFixed, - 'resizingConstraint': resizingConstraint, - 'resizingType': resizingType, - 'rotation': rotation, - 'sharedStyleID': sharedStyleID, - 'shouldBreakMaskChain': shouldBreakMaskChain, - 'hasClippingMask': hasClippingMask, - 'clippingMaskMode': clippingMaskMode, - 'userInfo': userInfo, - 'maintainScrollPosition': maintainScrollPosition, - 'prototypeNodeUUID': prototypeNodeUUID, - 'edited': edited, - 'isClosed': isClosed, - 'pointRadiusBehaviour': pointRadiusBehaviour, - 'points': points, - 'CLASS_NAME': CLASS_NAME, - 'absoluteBoundingBox': boundaryRectangle, - 'id': UUID, - 'type': type, - 'visible': isVisible, - 'style': style, - 'pbdfType': pbdfType, - }; - - @override - @JsonKey(ignore: true) - String pbdfType = 'triangle'; -} diff --git a/lib/input/sketch/entities/layers/triangle.g.dart b/lib/input/sketch/entities/layers/triangle.g.dart deleted file mode 100644 index 4164833a..00000000 --- a/lib/input/sketch/entities/layers/triangle.g.dart +++ /dev/null @@ -1,81 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'triangle.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Triangle _$TriangleFromJson(Map json) { - return Triangle( - edited: json['edited'] as bool, - isClosed: json['isClosed'] as bool, - pointRadiusBehaviour: json['pointRadiusBehaviour'], - points: json['points'] as List, - UUID: json['do_objectID'] as String, - booleanOperation: json['booleanOperation'], - exportOptions: json['exportOptions'], - boundaryRectangle: json['frame'] == null - ? null - : Frame.fromJson(json['frame'] as Map), - flow: json['flow'] == null - ? null - : Flow.fromJson(json['flow'] as Map), - isFixedToViewport: json['isFixedToViewport'], - isFlippedHorizontal: json['isFlippedHorizontal'], - isFlippedVertical: json['isFlippedVertical'], - isLocked: json['isLocked'], - isVisible: json['isVisible'], - layerListExpandedType: json['layerListExpandedType'], - name: json['name'], - nameIsFixed: json['nameIsFixed'], - resizingConstraint: json['resizingConstraint'], - resizingType: json['resizingType'], - rotation: json['rotation'], - sharedStyleID: json['sharedStyleID'], - shouldBreakMaskChain: json['shouldBreakMaskChain'], - hasClippingMask: json['hasClippingMask'], - clippingMaskMode: json['clippingMaskMode'], - userInfo: json['userInfo'], - style: json['style'] == null - ? null - : Style.fromJson(json['style'] as Map), - maintainScrollPosition: json['maintainScrollPosition'], - ) - ..prototypeNodeUUID = json['prototypeNodeUUID'] as String - ..CLASS_NAME = json['CLASS_NAME'] as String - ..type = json['_class'] as String; -} - -Map _$TriangleToJson(Triangle instance) => { - 'booleanOperation': instance.booleanOperation, - 'exportOptions': instance.exportOptions, - 'flow': instance.flow, - 'isFixedToViewport': instance.isFixedToViewport, - 'isFlippedHorizontal': instance.isFlippedHorizontal, - 'isFlippedVertical': instance.isFlippedVertical, - 'isLocked': instance.isLocked, - 'layerListExpandedType': instance.layerListExpandedType, - 'name': instance.name, - 'nameIsFixed': instance.nameIsFixed, - 'resizingConstraint': instance.resizingConstraint, - 'resizingType': instance.resizingType, - 'rotation': instance.rotation, - 'sharedStyleID': instance.sharedStyleID, - 'shouldBreakMaskChain': instance.shouldBreakMaskChain, - 'hasClippingMask': instance.hasClippingMask, - 'clippingMaskMode': instance.clippingMaskMode, - 'userInfo': instance.userInfo, - 'maintainScrollPosition': instance.maintainScrollPosition, - 'prototypeNodeUUID': instance.prototypeNodeUUID, - 'edited': instance.edited, - 'isClosed': instance.isClosed, - 'pointRadiusBehaviour': instance.pointRadiusBehaviour, - 'points': instance.points, - 'CLASS_NAME': instance.CLASS_NAME, - 'frame': instance.boundaryRectangle, - 'do_objectID': instance.UUID, - '_class': instance.type, - 'isVisible': instance.isVisible, - 'style': instance.style, - }; diff --git a/lib/input/sketch/entities/objects/foreign_symbol.dart b/lib/input/sketch/entities/objects/foreign_symbol.dart deleted file mode 100644 index c5e66a43..00000000 --- a/lib/input/sketch/entities/objects/foreign_symbol.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/symbol_master.dart'; -part 'foreign_symbol.g.dart'; - -@JsonSerializable(nullable: true) - -// title: Document -// description: The document entry in a Sketch file. -class ForeignSymbol { - static final String CLASS_NAME = 'MSImmutableForeignSymbol'; - final dynamic UUID; - final dynamic libraryID; - final String sourceLibraryName; - final bool symbolPrivate; - final SymbolMaster originalMaster; - final SymbolMaster symbolMaster; - - ForeignSymbol( - {this.UUID, - this.libraryID, - this.sourceLibraryName, - this.symbolPrivate, - this.originalMaster, - this.symbolMaster}); - factory ForeignSymbol.fromJson(Map json) => - _$ForeignSymbolFromJson(json); - Map toJson() => _$ForeignSymbolToJson(this); -} diff --git a/lib/input/sketch/entities/objects/foreign_symbol.g.dart b/lib/input/sketch/entities/objects/foreign_symbol.g.dart deleted file mode 100644 index 011e394a..00000000 --- a/lib/input/sketch/entities/objects/foreign_symbol.g.dart +++ /dev/null @@ -1,32 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'foreign_symbol.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -ForeignSymbol _$ForeignSymbolFromJson(Map json) { - return ForeignSymbol( - UUID: json['UUID'], - libraryID: json['libraryID'], - sourceLibraryName: json['sourceLibraryName'] as String, - symbolPrivate: json['symbolPrivate'] as bool, - originalMaster: json['originalMaster'] == null - ? null - : SymbolMaster.fromJson(json['originalMaster'] as Map), - symbolMaster: json['symbolMaster'] == null - ? null - : SymbolMaster.fromJson(json['symbolMaster'] as Map), - ); -} - -Map _$ForeignSymbolToJson(ForeignSymbol instance) => - { - 'UUID': instance.UUID, - 'libraryID': instance.libraryID, - 'sourceLibraryName': instance.sourceLibraryName, - 'symbolPrivate': instance.symbolPrivate, - 'originalMaster': instance.originalMaster, - 'symbolMaster': instance.symbolMaster, - }; diff --git a/lib/input/sketch/entities/objects/frame.dart b/lib/input/sketch/entities/objects/frame.dart deleted file mode 100644 index af1169f6..00000000 --- a/lib/input/sketch/entities/objects/frame.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/rect.dart'; - -part 'frame.g.dart'; - -@JsonSerializable(nullable: true) -class Frame implements Rect { - @JsonKey(name: '_class') - final String classField; - final bool constrainProportions; - @override - double height, width, x, y; - Frame({ - this.classField, - this.constrainProportions, - this.x, - this.y, - this.width, - this.height, - }); - factory Frame.fromJson(Map json) => _$FrameFromJson(json); - Map toJson() => _$FrameToJson(this); -} diff --git a/lib/input/sketch/entities/objects/frame.g.dart b/lib/input/sketch/entities/objects/frame.g.dart deleted file mode 100644 index 00a7ab27..00000000 --- a/lib/input/sketch/entities/objects/frame.g.dart +++ /dev/null @@ -1,27 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'frame.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Frame _$FrameFromJson(Map json) { - return Frame( - classField: json['_class'] as String, - constrainProportions: json['constrainProportions'] as bool, - x: (json['x'] as num)?.toDouble(), - y: (json['y'] as num)?.toDouble(), - width: (json['width'] as num)?.toDouble(), - height: (json['height'] as num)?.toDouble(), - ); -} - -Map _$FrameToJson(Frame instance) => { - '_class': instance.classField, - 'constrainProportions': instance.constrainProportions, - 'height': instance.height, - 'width': instance.width, - 'x': instance.x, - 'y': instance.y, - }; diff --git a/lib/input/sketch/entities/objects/override_property.dart b/lib/input/sketch/entities/objects/override_property.dart deleted file mode 100644 index fa066886..00000000 --- a/lib/input/sketch/entities/objects/override_property.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -part 'override_property.g.dart'; - -@JsonSerializable(nullable: true) - -/// title: Override Property -/// description: Defines override properties on symbol masters -class OverridableProperty { - static final String CLASS_NAME = 'MSImmutableOverrideProperty'; - final String overrideName; - final bool canOverride; - - OverridableProperty(this.overrideName, this.canOverride); - - factory OverridableProperty.fromJson(Map json) => - _$OverridablePropertyFromJson(json); - Map toJson() => _$OverridablePropertyToJson(this); -} diff --git a/lib/input/sketch/entities/objects/override_property.g.dart b/lib/input/sketch/entities/objects/override_property.g.dart deleted file mode 100644 index f7c38a18..00000000 --- a/lib/input/sketch/entities/objects/override_property.g.dart +++ /dev/null @@ -1,21 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'override_property.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -OverridableProperty _$OverridablePropertyFromJson(Map json) { - return OverridableProperty( - json['overrideName'] as String, - json['canOverride'] as bool, - ); -} - -Map _$OverridablePropertyToJson( - OverridableProperty instance) => - { - 'overrideName': instance.overrideName, - 'canOverride': instance.canOverride, - }; diff --git a/lib/input/sketch/entities/objects/override_value.dart b/lib/input/sketch/entities/objects/override_value.dart deleted file mode 100644 index f1678af9..00000000 --- a/lib/input/sketch/entities/objects/override_value.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -part 'override_value.g.dart'; - -@JsonSerializable(nullable: true) - -/// title: Override Property -/// description: Defines override properties on symbol masters -class OverridableValue { - static final String CLASS_NAME = 'overrideValue'; - final String overrideName; - @JsonKey(name: 'do_objectID') - final String UUID; - final dynamic value; - - OverridableValue(this.overrideName, this.UUID, this.value); - - factory OverridableValue.fromJson(Map json) => - _$OverridableValueFromJson(json); - Map toJson() => _$OverridableValueToJson(this); -} diff --git a/lib/input/sketch/entities/objects/override_value.g.dart b/lib/input/sketch/entities/objects/override_value.g.dart deleted file mode 100644 index e699fd1b..00000000 --- a/lib/input/sketch/entities/objects/override_value.g.dart +++ /dev/null @@ -1,22 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'override_value.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -OverridableValue _$OverridableValueFromJson(Map json) { - return OverridableValue( - json['overrideName'] as String, - json['do_objectID'] as String, - json['value'], - ); -} - -Map _$OverridableValueToJson(OverridableValue instance) => - { - 'overrideName': instance.overrideName, - 'do_objectID': instance.UUID, - 'value': instance.value, - }; diff --git a/lib/input/sketch/entities/style/blur.dart b/lib/input/sketch/entities/style/blur.dart deleted file mode 100644 index 3abe0c42..00000000 --- a/lib/input/sketch/entities/style/blur.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -part 'blur.g.dart'; - -@JsonSerializable(nullable: true) -class Blur{ - @JsonKey(name: '_class') - final String classField; - final bool isEnabled; - final String center; - final double motionAngle, radius, saturation, type; - - Blur({this.center, this.classField, this.isEnabled, this.motionAngle, this.radius, this.saturation, this.type}); - - factory Blur.fromJson(Map json) =>_$BlurFromJson(json); - Map toJson() => _$BlurToJson(this); -} diff --git a/lib/input/sketch/entities/style/blur.g.dart b/lib/input/sketch/entities/style/blur.g.dart deleted file mode 100644 index 6ccb3d04..00000000 --- a/lib/input/sketch/entities/style/blur.g.dart +++ /dev/null @@ -1,29 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'blur.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Blur _$BlurFromJson(Map json) { - return Blur( - center: json['center'] as String, - classField: json['_class'] as String, - isEnabled: json['isEnabled'] as bool, - motionAngle: (json['motionAngle'] as num)?.toDouble(), - radius: (json['radius'] as num)?.toDouble(), - saturation: (json['saturation'] as num)?.toDouble(), - type: (json['type'] as num)?.toDouble(), - ); -} - -Map _$BlurToJson(Blur instance) => { - '_class': instance.classField, - 'isEnabled': instance.isEnabled, - 'center': instance.center, - 'motionAngle': instance.motionAngle, - 'radius': instance.radius, - 'saturation': instance.saturation, - 'type': instance.type, - }; diff --git a/lib/input/sketch/entities/style/border.dart b/lib/input/sketch/entities/style/border.dart deleted file mode 100644 index 5a033a95..00000000 --- a/lib/input/sketch/entities/style/border.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color.dart'; -import 'package:parabeac_core/input/sketch/entities/style/context_settings.dart'; -import 'package:parabeac_core/input/sketch/entities/style/gradient.dart'; -import 'package:parabeac_core/design_logic/pb_border.dart'; -part 'border.g.dart'; - -@JsonSerializable(nullable: true) -class Border implements PBBorder{ - @JsonKey(name: '_class') - final String classField; - @override - final bool isEnabled; - @override - final double fillType; - @override - final Color color; - final ContextSettings contextSettings; - final Gradient gradient; - final double position; - @override - final double thickness; - - Border( - {this.classField, - this.color, - this.contextSettings, - this.fillType, - this.gradient, - this.isEnabled, - this.position, - this.thickness}); - - factory Border.fromJson(Map json) => _$BorderFromJson(json); - @override - Map toJson() => _$BorderToJson(this); -} diff --git a/lib/input/sketch/entities/style/border.g.dart b/lib/input/sketch/entities/style/border.g.dart deleted file mode 100644 index ce6dc010..00000000 --- a/lib/input/sketch/entities/style/border.g.dart +++ /dev/null @@ -1,38 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'border.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Border _$BorderFromJson(Map json) { - return Border( - classField: json['_class'] as String, - color: json['color'] == null - ? null - : Color.fromJson(json['color'] as Map), - contextSettings: json['contextSettings'] == null - ? null - : ContextSettings.fromJson( - json['contextSettings'] as Map), - fillType: (json['fillType'] as num)?.toDouble(), - gradient: json['gradient'] == null - ? null - : Gradient.fromJson(json['gradient'] as Map), - isEnabled: json['isEnabled'] as bool, - position: (json['position'] as num)?.toDouble(), - thickness: (json['thickness'] as num)?.toDouble(), - ); -} - -Map _$BorderToJson(Border instance) => { - '_class': instance.classField, - 'isEnabled': instance.isEnabled, - 'fillType': instance.fillType, - 'color': instance.color, - 'contextSettings': instance.contextSettings, - 'gradient': instance.gradient, - 'position': instance.position, - 'thickness': instance.thickness, - }; diff --git a/lib/input/sketch/entities/style/border_options.dart b/lib/input/sketch/entities/style/border_options.dart deleted file mode 100644 index fb6185f3..00000000 --- a/lib/input/sketch/entities/style/border_options.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/pb_border_options.dart'; -part 'border_options.g.dart'; - -@JsonSerializable(nullable: true) -class BorderOptions implements PBBorderOptions { - @JsonKey(name: '_class') - String classField; - @override - bool isEnabled; - @override - List dashPattern; - @override - int lineCapStyle, lineJoinStyle; - - BorderOptions( - this.classField, - this.dashPattern, - this.isEnabled, - this.lineCapStyle, - this.lineJoinStyle, - ); - - factory BorderOptions.fromJson(Map json) => _$BorderOptionsFromJson(json); - @override - Map toJson() => _$BorderOptionsToJson(this); -} diff --git a/lib/input/sketch/entities/style/border_options.g.dart b/lib/input/sketch/entities/style/border_options.g.dart deleted file mode 100644 index 5e09807e..00000000 --- a/lib/input/sketch/entities/style/border_options.g.dart +++ /dev/null @@ -1,26 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'border_options.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -BorderOptions _$BorderOptionsFromJson(Map json) { - return BorderOptions( - json['_class'] as String, - json['dashPattern'] as List, - json['isEnabled'] as bool, - json['lineCapStyle'] as int, - json['lineJoinStyle'] as int, - ); -} - -Map _$BorderOptionsToJson(BorderOptions instance) => - { - '_class': instance.classField, - 'isEnabled': instance.isEnabled, - 'dashPattern': instance.dashPattern, - 'lineCapStyle': instance.lineCapStyle, - 'lineJoinStyle': instance.lineJoinStyle, - }; diff --git a/lib/input/sketch/entities/style/color.dart b/lib/input/sketch/entities/style/color.dart deleted file mode 100644 index d67185e4..00000000 --- a/lib/input/sketch/entities/style/color.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/color.dart'; - -part 'color.g.dart'; - -@JsonSerializable(nullable: true) -class Color implements PBColor { - @JsonKey(name: '_class') - final String classField; - @override - double alpha, blue, green, red; - - Color({this.alpha, this.blue, this.classField, this.green, this.red}); - - factory Color.fromJson(Map json) => _$ColorFromJson(json); - @override - Map toJson() => _$ColorToJson(this); -} diff --git a/lib/input/sketch/entities/style/color.g.dart b/lib/input/sketch/entities/style/color.g.dart deleted file mode 100644 index c5aab197..00000000 --- a/lib/input/sketch/entities/style/color.g.dart +++ /dev/null @@ -1,25 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'color.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Color _$ColorFromJson(Map json) { - return Color( - alpha: (json['alpha'] as num)?.toDouble(), - blue: (json['blue'] as num)?.toDouble(), - classField: json['_class'] as String, - green: (json['green'] as num)?.toDouble(), - red: (json['red'] as num)?.toDouble(), - ); -} - -Map _$ColorToJson(Color instance) => { - '_class': instance.classField, - 'alpha': instance.alpha, - 'blue': instance.blue, - 'green': instance.green, - 'red': instance.red, - }; diff --git a/lib/input/sketch/entities/style/color_controls.dart b/lib/input/sketch/entities/style/color_controls.dart deleted file mode 100644 index 53605754..00000000 --- a/lib/input/sketch/entities/style/color_controls.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -part 'color_controls.g.dart'; - -@JsonSerializable(nullable: true) -class ColorControls{ - @JsonKey(name: '_class') - final String classField; - final bool isEnabled; - final double brightness, contrast, hue, saturation; - - ColorControls({this.brightness, this.classField, this.contrast, this.hue, this.isEnabled, this.saturation}); - - factory ColorControls.fromJson(Map json) =>_$ColorControlsFromJson(json); - Map toJson() => _$ColorControlsToJson(this); -} diff --git a/lib/input/sketch/entities/style/color_controls.g.dart b/lib/input/sketch/entities/style/color_controls.g.dart deleted file mode 100644 index 34d912b9..00000000 --- a/lib/input/sketch/entities/style/color_controls.g.dart +++ /dev/null @@ -1,28 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'color_controls.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -ColorControls _$ColorControlsFromJson(Map json) { - return ColorControls( - brightness: (json['brightness'] as num)?.toDouble(), - classField: json['_class'] as String, - contrast: (json['contrast'] as num)?.toDouble(), - hue: (json['hue'] as num)?.toDouble(), - isEnabled: json['isEnabled'] as bool, - saturation: (json['saturation'] as num)?.toDouble(), - ); -} - -Map _$ColorControlsToJson(ColorControls instance) => - { - '_class': instance.classField, - 'isEnabled': instance.isEnabled, - 'brightness': instance.brightness, - 'contrast': instance.contrast, - 'hue': instance.hue, - 'saturation': instance.saturation, - }; diff --git a/lib/input/sketch/entities/style/context_settings.dart b/lib/input/sketch/entities/style/context_settings.dart deleted file mode 100644 index a609dddf..00000000 --- a/lib/input/sketch/entities/style/context_settings.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -part 'context_settings.g.dart'; - -@JsonSerializable(nullable: true) -class ContextSettings{ - @JsonKey(name: '_class') - final String classField; - final double blendMode, opacity; - - ContextSettings({this.blendMode, this.classField, this.opacity}); - - factory ContextSettings.fromJson(Map json) =>_$ContextSettingsFromJson(json); - Map toJson() => _$ContextSettingsToJson(this); -} diff --git a/lib/input/sketch/entities/style/context_settings.g.dart b/lib/input/sketch/entities/style/context_settings.g.dart deleted file mode 100644 index ef6585af..00000000 --- a/lib/input/sketch/entities/style/context_settings.g.dart +++ /dev/null @@ -1,22 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'context_settings.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -ContextSettings _$ContextSettingsFromJson(Map json) { - return ContextSettings( - blendMode: (json['blendMode'] as num)?.toDouble(), - classField: json['_class'] as String, - opacity: (json['opacity'] as num)?.toDouble(), - ); -} - -Map _$ContextSettingsToJson(ContextSettings instance) => - { - '_class': instance.classField, - 'blendMode': instance.blendMode, - 'opacity': instance.opacity, - }; diff --git a/lib/input/sketch/entities/style/fill.dart b/lib/input/sketch/entities/style/fill.dart deleted file mode 100644 index 3b36654f..00000000 --- a/lib/input/sketch/entities/style/fill.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/pb_fill.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color.dart'; -import 'package:parabeac_core/input/sketch/entities/style/context_settings.dart'; -import 'package:parabeac_core/input/sketch/entities/style/gradient.dart'; -part 'fill.g.dart'; - -@JsonSerializable(nullable: true) -class Fill implements PBFill { - @JsonKey(name: '_class') - final String classField; - @override - bool isEnabled; - @override - int fillType; - @override - PBColor color; - final ContextSettings contextSettings; - final Gradient gradient; - final int noiseIndex; - final int noiseIntensity; - final int patternFillType; - final int patternTileScale; - - Fill( - {this.classField, - Color this.color, - this.contextSettings, - this.fillType, - this.gradient, - this.isEnabled, - this.noiseIndex, - this.noiseIntensity, - this.patternFillType, - this.patternTileScale}); - - factory Fill.fromJson(Map json) => _$FillFromJson(json); - @override - Map toJson() => _$FillToJson(this); -} diff --git a/lib/input/sketch/entities/style/fill.g.dart b/lib/input/sketch/entities/style/fill.g.dart deleted file mode 100644 index 22279662..00000000 --- a/lib/input/sketch/entities/style/fill.g.dart +++ /dev/null @@ -1,42 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'fill.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Fill _$FillFromJson(Map json) { - return Fill( - classField: json['_class'] as String, - color: json['color'] == null - ? null - : Color.fromJson(json['color'] as Map), - contextSettings: json['contextSettings'] == null - ? null - : ContextSettings.fromJson( - json['contextSettings'] as Map), - fillType: json['fillType'] as int, - gradient: json['gradient'] == null - ? null - : Gradient.fromJson(json['gradient'] as Map), - isEnabled: json['isEnabled'] as bool, - noiseIndex: json['noiseIndex'] as int, - noiseIntensity: json['noiseIntensity'] as int, - patternFillType: json['patternFillType'] as int, - patternTileScale: json['patternTileScale'] as int, - ); -} - -Map _$FillToJson(Fill instance) => { - '_class': instance.classField, - 'isEnabled': instance.isEnabled, - 'fillType': instance.fillType, - 'color': instance.color, - 'contextSettings': instance.contextSettings, - 'gradient': instance.gradient, - 'noiseIndex': instance.noiseIndex, - 'noiseIntensity': instance.noiseIntensity, - 'patternFillType': instance.patternFillType, - 'patternTileScale': instance.patternTileScale, - }; diff --git a/lib/input/sketch/entities/style/font_descriptor.dart b/lib/input/sketch/entities/style/font_descriptor.dart deleted file mode 100644 index c82350ca..00000000 --- a/lib/input/sketch/entities/style/font_descriptor.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/pb_font_descriptor.dart'; -part 'font_descriptor.g.dart'; - -@JsonSerializable(nullable: true) -class FontDescriptor implements PBFontDescriptor { - @override - @JsonKey(name: 'attributes') - Map rawAttributes; - @override - @JsonKey(ignore: true) - String fontName; - @override - @JsonKey(ignore: true) - num fontSize; - @JsonKey(ignore: true) - String fontWeight; - @JsonKey(ignore: true) - String fontStyle; - @JsonKey(ignore: true) - num letterSpacing; - - FontDescriptor({this.rawAttributes}) { - fontSize = rawAttributes['size']; - fontName = rawAttributes['name']; - } - - factory FontDescriptor.fromJson(Map json) => - _$FontDescriptorFromJson(json); - - Map toJson() => _$FontDescriptorToJson(this); -} diff --git a/lib/input/sketch/entities/style/font_descriptor.g.dart b/lib/input/sketch/entities/style/font_descriptor.g.dart deleted file mode 100644 index 007c8d76..00000000 --- a/lib/input/sketch/entities/style/font_descriptor.g.dart +++ /dev/null @@ -1,18 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'font_descriptor.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FontDescriptor _$FontDescriptorFromJson(Map json) { - return FontDescriptor( - rawAttributes: json['attributes'] as Map, - ); -} - -Map _$FontDescriptorToJson(FontDescriptor instance) => - { - 'attributes': instance.rawAttributes, - }; diff --git a/lib/input/sketch/entities/style/gradient.dart b/lib/input/sketch/entities/style/gradient.dart deleted file mode 100644 index e2ebabf1..00000000 --- a/lib/input/sketch/entities/style/gradient.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/sketch/entities/style/gradient_stop.dart'; -part 'gradient.g.dart'; - -@JsonSerializable(nullable: true) -class Gradient { - @JsonKey(name: '_class') - final String classField; - final double elipseLength; - final String from; - final double gradientType; - final String to; - final List stops; - - Gradient( - {this.classField, - this.elipseLength, - this.from, - this.gradientType, - this.stops, - this.to}); - - factory Gradient.fromJson(Map json) => _$GradientFromJson(json); - Map toJson() => _$GradientToJson(this); -} diff --git a/lib/input/sketch/entities/style/gradient.g.dart b/lib/input/sketch/entities/style/gradient.g.dart deleted file mode 100644 index 799f57f1..00000000 --- a/lib/input/sketch/entities/style/gradient.g.dart +++ /dev/null @@ -1,30 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'gradient.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Gradient _$GradientFromJson(Map json) { - return Gradient( - classField: json['_class'] as String, - elipseLength: (json['elipseLength'] as num)?.toDouble(), - from: json['from'] as String, - gradientType: (json['gradientType'] as num)?.toDouble(), - stops: (json['stops'] as List) - ?.map((e) => - e == null ? null : GradientStop.fromJson(e as Map)) - ?.toList(), - to: json['to'] as String, - ); -} - -Map _$GradientToJson(Gradient instance) => { - '_class': instance.classField, - 'elipseLength': instance.elipseLength, - 'from': instance.from, - 'gradientType': instance.gradientType, - 'to': instance.to, - 'stops': instance.stops, - }; diff --git a/lib/input/sketch/entities/style/gradient_stop.dart b/lib/input/sketch/entities/style/gradient_stop.dart deleted file mode 100644 index 2a096fab..00000000 --- a/lib/input/sketch/entities/style/gradient_stop.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color.dart'; -part 'gradient_stop.g.dart'; - -@JsonSerializable(nullable: true) -class GradientStop { - @JsonKey(name: '_class') - final String classField; - final double position; - final Color color; - - GradientStop({this.classField, this.color, this.position}); - - factory GradientStop.fromJson(Map json) => _$GradientStopFromJson(json); - Map toJson() => _$GradientStopToJson(this); -} diff --git a/lib/input/sketch/entities/style/gradient_stop.g.dart b/lib/input/sketch/entities/style/gradient_stop.g.dart deleted file mode 100644 index 7c392318..00000000 --- a/lib/input/sketch/entities/style/gradient_stop.g.dart +++ /dev/null @@ -1,24 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'gradient_stop.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -GradientStop _$GradientStopFromJson(Map json) { - return GradientStop( - classField: json['_class'] as String, - color: json['color'] == null - ? null - : Color.fromJson(json['color'] as Map), - position: (json['position'] as num)?.toDouble(), - ); -} - -Map _$GradientStopToJson(GradientStop instance) => - { - '_class': instance.classField, - 'position': instance.position, - 'color': instance.color, - }; diff --git a/lib/input/sketch/entities/style/paragraph_style.dart b/lib/input/sketch/entities/style/paragraph_style.dart deleted file mode 100644 index 2070e81b..00000000 --- a/lib/input/sketch/entities/style/paragraph_style.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/pb_paragraph_style.dart'; -part 'paragraph_style.g.dart'; - -@JsonSerializable(nullable: true) -class ParagraphStyle implements PBParagraphStyle { - @override - int alignment; - - ParagraphStyle({this.alignment}); - - factory ParagraphStyle.fromJson(Map json) => - _$ParagraphStyleFromJson(json); - - Map toJson() => _$ParagraphStyleToJson(this); -} diff --git a/lib/input/sketch/entities/style/paragraph_style.g.dart b/lib/input/sketch/entities/style/paragraph_style.g.dart deleted file mode 100644 index 2a4dbdfd..00000000 --- a/lib/input/sketch/entities/style/paragraph_style.g.dart +++ /dev/null @@ -1,18 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'paragraph_style.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -ParagraphStyle _$ParagraphStyleFromJson(Map json) { - return ParagraphStyle( - alignment: json['alignment'] as int, - ); -} - -Map _$ParagraphStyleToJson(ParagraphStyle instance) => - { - 'alignment': instance.alignment, - }; diff --git a/lib/input/sketch/entities/style/shared_style.dart b/lib/input/sketch/entities/style/shared_style.dart deleted file mode 100644 index 203c5cd8..00000000 --- a/lib/input/sketch/entities/style/shared_style.dart +++ /dev/null @@ -1,135 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:recase/recase.dart'; - -part 'shared_style.g.dart'; - -Map SharedStyle_UUIDToName = {}; - -@JsonSerializable(nullable: true) -class SharedStyle with PBColorMixin { - @JsonKey(name: '_class') - final String classField; - @override - @JsonKey(name: 'do_objectID') - String UUID; - @JsonKey(name: 'name') - String name; - @JsonKey(name: 'value') - Style style; - - SharedStyle({ - this.classField, - this.UUID, - this.name, - this.style, - }) { - name = name.camelCase; - SharedStyle_UUIDToName[UUID] = name.replaceAll( - RegExp( - r'[^A-Za-z0-9_]', - ), - ''); - } - - String generate() { - var buffer = StringBuffer(); - - if (style != null) { - buffer.write('SK_Style ${name} = SK_Style(\n'); - var bgc = style.backgroundColor; - if (bgc == null) { - buffer.write('null,\t\t// backgroundColor\n'); - } else { - buffer.write( - 'Color.fromARGB(${(bgc.alpha * 255.0).toInt()}, ${(bgc.red * 255.0).toInt()}, ${(bgc.green * 255.0).toInt()}, ${(bgc.blue * 255.0).toInt()}),\n'); - } - - var fills = style.fills; - if (fills == null) { - buffer.write('null,\t\t// List\n'); - } else { - buffer.write('[\n'); - fills.forEach((fill) { - buffer.write('SK_Fill('); - if (fill.color == null) { - buffer.write('null, ${fill.isEnabled})\t\t// fill.color\n'); - } else { - buffer.write( - 'Color.fromARGB(${(fill.color.alpha * 255.0).toInt()}, ${(fill.color.red * 255.0).toInt()}, ${(fill.color.green * 255.0).toInt()}, ${(fill.color.blue * 255.0).toInt()}), ${fill.isEnabled})\n'); - } - }); - buffer.write('],\n'); - } - var borders = style.borders; - if (borders == null) { - buffer.write('null,\t\t// borders\n'); - } else { - buffer.write('[\n'); - borders.forEach((border) { - buffer.write('SK_Border(${border.isEnabled}, ${border.fillType}, '); - if (border.color == null) { - buffer.write('null,\t\t// border.color\n'); - } else { - buffer.write( - 'Color.fromARGB(${(border.color.alpha * 255.0).toInt()}, ${(border.color.red * 255.0).toInt()}, ${(border.color.green * 255.0).toInt()}, ${(border.color.blue * 255.0).toInt()}), ${border.thickness}),\n'); - } - }); - buffer.write('],\n'); - } - var bo = style.borderOptions; - if (bo == null) { - buffer.write('null,,\t\t// borderOptions\n'); - } else { - // TODO if dashPattern is used figure out how to export, using null for now - buffer.write( - 'SK_BorderOptions(${bo.isEnabled}, null, ${bo.lineCapStyle}, ${bo.lineJoinStyle}),\n'); - } - - if (style.textStyle == null) { - buffer.write('null,\t\t// textStyle\n'); - } else { - var ts = style.textStyle; - var fd = ts.fontDescriptor as FontDescriptor; - buffer.write('TextStyle(\n'); - if (fd.fontName != null) { - buffer.write('fontFamily: \'${fd.fontName}\',\n'); - } - if (fd.fontSize != null) { - buffer.write('fontSize: ${fd.fontSize.toString()},\n'); - } - if (fd.fontWeight != null) { - buffer.write('fontWeight: FontWeight.${fd.fontWeight.toString()},\n'); - } - - if (fd.fontStyle != null) { - buffer.write('fontStyle: FontStyle.${fd.fontStyle},\n'); - } - if (fd.letterSpacing != null) { - buffer.write('letterSpacing: ${fd.letterSpacing},\n'); - } - - if (ts.fontColor != null) { - var color = toHex(ts.fontColor); - var defColor = findDefaultColor(color); - if (defColor == null) { - buffer.write('color: Color($color),'); - } else { - buffer.write('color: $defColor,'); - } - } - - buffer.write('),\n'); - } - buffer.write('${style.hasShadow});\n'); - } - - return buffer.toString(); - } - - factory SharedStyle.fromJson(Map json) => _$SharedStyleFromJson(json); - - Map toJson() => _$SharedStyleToJson(this); -} diff --git a/lib/input/sketch/entities/style/shared_style.g.dart b/lib/input/sketch/entities/style/shared_style.g.dart deleted file mode 100644 index 7588e51c..00000000 --- a/lib/input/sketch/entities/style/shared_style.g.dart +++ /dev/null @@ -1,26 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'shared_style.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -SharedStyle _$SharedStyleFromJson(Map json) { - return SharedStyle( - classField: json['_class'] as String, - UUID: json['do_objectID'] as String, - name: json['name'] as String, - style: json['value'] == null - ? null - : Style.fromJson(json['value'] as Map), - ); -} - -Map _$SharedStyleToJson(SharedStyle instance) => - { - '_class': instance.classField, - 'do_objectID': instance.UUID, - 'name': instance.name, - 'value': instance.style, - }; diff --git a/lib/input/sketch/entities/style/style.dart b/lib/input/sketch/entities/style/style.dart deleted file mode 100644 index 89d7e248..00000000 --- a/lib/input/sketch/entities/style/style.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/pb_border.dart'; -import 'package:parabeac_core/design_logic/pb_border_options.dart'; -import 'package:parabeac_core/design_logic/pb_fill.dart'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/pb_style.dart'; -import 'package:parabeac_core/design_logic/pb_text_style.dart'; -import 'package:parabeac_core/input/sketch/entities/style/border.dart'; -import 'package:parabeac_core/input/sketch/entities/style/border_options.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color_controls.dart'; -import 'package:parabeac_core/input/sketch/entities/style/context_settings.dart'; -import 'package:parabeac_core/input/sketch/entities/style/fill.dart'; -import 'package:parabeac_core/input/sketch/entities/style/text_style.dart'; -import 'package:parabeac_core/input/sketch/entities/style/blur.dart'; -part 'style.g.dart'; - -@JsonSerializable(nullable: true) -class Style implements PBStyle { - @JsonKey(name: '_class') - final String classField; - @override - @JsonKey(name: 'do_objectID') - String UUID; - final int endMarkerType, miterLimit, startMarkerType, windingRule; - final Blur blur; - @override - final BorderOptions borderOptions; - @override - final List borders; - final ColorControls colorControls; - final ContextSettings contextSettings; - @override - List fills, innerShadows, shadows; - @override - @JsonKey(nullable: true) - PBTextStyle textStyle; - - Style({ - this.blur, - this.borderOptions, - this.borders, - this.classField, - this.colorControls, - this.contextSettings, - this.UUID, - this.endMarkerType, - List this.fills, - List this.innerShadows, - this.miterLimit, - List this.shadows, - this.startMarkerType, - this.windingRule, - TextStyle this.textStyle, - this.backgroundColor, - this.hasShadow, - }) { - if (shadows != null) { - shadows = null; - innerShadows = null; - hasShadow = true; - } - // TODO: add rectangle fill types, for now just copy the fill[0] to the background color - if (fills != null && fills.isNotEmpty) { - if (fills[0].isEnabled && (fills[0].fillType == 0)) { - backgroundColor = fills[0].color; - } - } - } - - factory Style.fromJson(Map json) => _$StyleFromJson(json); - @override - Map toJson() => _$StyleToJson(this); - - @override - @JsonKey(ignore: true) - PBColor backgroundColor; - - @override - set borderOptions(PBBorderOptions _borderOptions) {} - - @override - set borders(List _borders) {} - - @override - @JsonKey(ignore: true) - bool hasShadow; -} diff --git a/lib/input/sketch/entities/style/style.g.dart b/lib/input/sketch/entities/style/style.g.dart deleted file mode 100644 index b7c26d14..00000000 --- a/lib/input/sketch/entities/style/style.g.dart +++ /dev/null @@ -1,68 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'style.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Style _$StyleFromJson(Map json) { - return Style( - blur: json['blur'] == null - ? null - : Blur.fromJson(json['blur'] as Map), - borderOptions: json['borderOptions'] == null - ? null - : BorderOptions.fromJson(json['borderOptions'] as Map), - borders: (json['borders'] as List) - ?.map((e) => - e == null ? null : Border.fromJson(e as Map)) - ?.toList(), - classField: json['_class'] as String, - colorControls: json['colorControls'] == null - ? null - : ColorControls.fromJson(json['colorControls'] as Map), - contextSettings: json['contextSettings'] == null - ? null - : ContextSettings.fromJson( - json['contextSettings'] as Map), - UUID: json['do_objectID'] as String, - endMarkerType: json['endMarkerType'] as int, - fills: (json['fills'] as List) - ?.map( - (e) => e == null ? null : Fill.fromJson(e as Map)) - ?.toList(), - innerShadows: (json['innerShadows'] as List) - ?.map( - (e) => e == null ? null : Fill.fromJson(e as Map)) - ?.toList(), - miterLimit: json['miterLimit'] as int, - shadows: (json['shadows'] as List) - ?.map( - (e) => e == null ? null : Fill.fromJson(e as Map)) - ?.toList(), - startMarkerType: json['startMarkerType'] as int, - windingRule: json['windingRule'] as int, - textStyle: json['textStyle'] == null - ? null - : TextStyle.fromJson(json['textStyle'] as Map), - ); -} - -Map _$StyleToJson(Style instance) => { - '_class': instance.classField, - 'do_objectID': instance.UUID, - 'endMarkerType': instance.endMarkerType, - 'miterLimit': instance.miterLimit, - 'startMarkerType': instance.startMarkerType, - 'windingRule': instance.windingRule, - 'blur': instance.blur, - 'borderOptions': instance.borderOptions, - 'borders': instance.borders, - 'colorControls': instance.colorControls, - 'contextSettings': instance.contextSettings, - 'fills': instance.fills, - 'innerShadows': instance.innerShadows, - 'shadows': instance.shadows, - 'textStyle': instance.textStyle, - }; diff --git a/lib/input/sketch/entities/style/text_style.dart b/lib/input/sketch/entities/style/text_style.dart deleted file mode 100644 index d776c58b..00000000 --- a/lib/input/sketch/entities/style/text_style.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/pb_font_descriptor.dart'; -import 'package:parabeac_core/design_logic/pb_paragraph_style.dart'; -import 'package:parabeac_core/design_logic/pb_text_style.dart'; -import 'package:parabeac_core/input/sketch/entities/style/color.dart'; -import 'package:parabeac_core/input/sketch/entities/style/font_descriptor.dart'; -import 'package:parabeac_core/input/sketch/entities/style/paragraph_style.dart'; -part 'text_style.g.dart'; - -@JsonSerializable(nullable: true) -class TextStyle implements PBTextStyle { - @JsonKey(name: 'encodedAttributes') - Map rawEncodedAttributes; - @override - @JsonKey(ignore: true) - PBFontDescriptor fontDescriptor; - @override - @JsonKey(ignore: true) - PBParagraphStyle paragraphStyle; - @JsonKey(ignore: true) - num verticalAlignment; - @JsonKey(ignore: true) - String style; - - /// List of possible text weights, sorted by longest string first for .contains - final List STYLES = [ - 'ExtraLightItalic', - 'ExtraBoldItalic', - 'SemiBoldItalic', - 'MediumItalic', - 'LightItalic', - 'BlackItalic', - 'ThinItalic', - 'ExtraLight', - 'BoldItalic', - 'ExtraBold', - 'SemiBold', - 'Regular', - 'Italic', - 'Medium', - 'Light', - 'Black', - 'Bold', - 'Thin', -// 'BoldOblique', -// 'LightOblique', -// 'Oblique', - ]; - - final Map> fontInfo = { - 'Thin': {'fontWeight': 'w100', 'fontStyle': 'normal'}, - 'ThinItalic': {'fontWeight': 'w100', 'fontStyle': 'italic'}, - 'ExtraLight': {'fontWeight': 'w200', 'fontStyle': 'normal'}, - 'ExtraLightItalic': {'fontWeight': 'w200', 'fontStyle': 'italic'}, - 'Light': {'fontWeight': 'w300', 'fontStyle': 'normal'}, - 'LightItalic': {'fontWeight': 'w300', 'fontStyle': 'italic'}, - 'Regular': {'fontWeight': 'w400', 'fontStyle': 'normal'}, - 'Italic': {'fontWeight': 'w400', 'fontStyle': 'italic'}, - 'Medium': {'fontWeight': 'w500', 'fontStyle': 'normal'}, - 'MediumItalic': {'fontWeight': 'w500', 'fontStyle': 'italic'}, - 'SemiBold': {'fontWeight': 'w600', 'fontStyle': 'normal'}, - 'SemiBoldItalic': {'fontWeight': 'w600', 'fontStyle': 'italic'}, - 'Bold': {'fontWeight': 'w700', 'fontStyle': 'normal'}, - 'BoldItalic': {'fontWeight': 'w700', 'fontStyle': 'italic'}, - 'ExtraBold': {'fontWeight': 'w800', 'fontStyle': 'normal'}, - 'ExtraBoldItalic': {'fontWeight': 'w800', 'fontStyle': 'italic'}, - 'Black': {'fontWeight': 'w900', 'fontStyle': 'normal'}, - 'BlackItalic': {'fontWeight': 'w900', 'fontStyle': 'italic'}, - }; - - TextStyle({this.rawEncodedAttributes}) { - fontColor = Color.fromJson( - rawEncodedAttributes['MSAttributedStringColorAttribute']); - fontDescriptor = FontDescriptor.fromJson( - rawEncodedAttributes['MSAttributedStringFontAttribute']); - paragraphStyle = - ParagraphStyle.fromJson(rawEncodedAttributes['paragraphStyle'] ?? {}); - verticalAlignment = rawEncodedAttributes['textStyleVerticalAlignment']; - - //Find if text has special weight - for (var s in STYLES) { - if (fontDescriptor.fontName.contains(s)) { - // this is really a mapping of style to weight - (fontDescriptor as FontDescriptor).fontWeight = - fontInfo[s]['fontWeight']; - // this is only normal, italic style - (fontDescriptor as FontDescriptor).fontStyle = fontInfo[s]['fontStyle']; - // this is really fontFamily with removal of -XXX font type name suffix - (fontDescriptor as FontDescriptor).fontName = - fontDescriptor.fontName.replaceFirst('-$s', ''); - (fontDescriptor as FontDescriptor).letterSpacing = - rawEncodedAttributes['kerning'] ?? 0.0; - break; - } - } - } - - factory TextStyle.fromJson(Map json) => - _$TextStyleFromJson(json); - @override - Map toJson() => _$TextStyleToJson(this); - - @override - @JsonKey(ignore: true) - PBColor fontColor; - - @override - String fontFamily; - - @override - String fontSize; - - @override - String fontWeight; - - @override - String weight; -} diff --git a/lib/input/sketch/entities/style/text_style.g.dart b/lib/input/sketch/entities/style/text_style.g.dart deleted file mode 100644 index 32877b8e..00000000 --- a/lib/input/sketch/entities/style/text_style.g.dart +++ /dev/null @@ -1,25 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'text_style.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -TextStyle _$TextStyleFromJson(Map json) { - return TextStyle( - rawEncodedAttributes: json['encodedAttributes'] as Map, - ) - ..fontFamily = json['fontFamily'] as String - ..fontSize = json['fontSize'] as String - ..fontWeight = json['fontWeight'] as String - ..weight = json['weight'] as String; -} - -Map _$TextStyleToJson(TextStyle instance) => { - 'encodedAttributes': instance.rawEncodedAttributes, - 'fontFamily': instance.fontFamily, - 'fontSize': instance.fontSize, - 'fontWeight': instance.fontWeight, - 'weight': instance.weight, - }; diff --git a/lib/input/sketch/helper/sketch_asset_processor.dart b/lib/input/sketch/helper/sketch_asset_processor.dart deleted file mode 100644 index ac0820d8..00000000 --- a/lib/input/sketch/helper/sketch_asset_processor.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'dart:typed_data'; -import 'package:http/http.dart' as http; -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/input/helper/asset_processing_service.dart'; -import 'package:quick_log/quick_log.dart'; - -class SketchAssetProcessor extends AssetProcessingService { - final svg_convertion_endpoint = - Platform.environment.containsKey('SAC_ENDPOINT') - ? Platform.environment['SAC_ENDPOINT'] - : 'http://localhost:4000/vector/local'; - - Logger log = Logger('Image conversion'); - - SketchAssetProcessor._internal(); - - static final SketchAssetProcessor _instance = - SketchAssetProcessor._internal(); - - factory SketchAssetProcessor() => _instance; - - String getBlobName(String path) => path.split('/').last; - - /// Converts an svg with `uuid` from a sketch file to a png with specified - /// `width` and `height` - @override - Future processImage(String uuid, [num width, num height]) async { - try { - var body = Platform.environment.containsKey('SAC_ENDPOINT') - ? { - 'uuid': uuid, - 'width': width, - 'height': height, - 'blob': getBlobName(MainInfo().designFilePath), - 'container': 'design-file' - } - : { - 'uuid': uuid, - 'path': MainInfo().designFilePath, - 'width': width, - 'height': height - }; - - var response = await http - .post( - svg_convertion_endpoint, - headers: {HttpHeaders.contentTypeHeader: 'application/json'}, - body: jsonEncode(body), - ) - .timeout(Duration(minutes: 1)); - - if (response.statusCode >= 400) { - var bodyMap = jsonDecode(response.body); - log.error(bodyMap['error']); - } - return response?.bodyBytes; - } catch (e) { - var imageErr = File( - '${MainInfo().cwd.path}/lib/input/assets/image-conversion-error.png') - .readAsBytesSync(); - await MainInfo().sentry.captureException(exception: e); - log.error(e.toString()); - return imageErr; - } - } - - @override - Future processRootElements(Map uuids) async { - for (var entry in uuids.entries) { - var image = await processImage( - entry.key, uuids[entry.key]['width'], uuids[entry.key]['height']); - await super.uploadToStorage(image, entry.key); - } - } -} diff --git a/lib/input/sketch/helper/sketch_page.dart b/lib/input/sketch/helper/sketch_page.dart deleted file mode 100644 index a17f6984..00000000 --- a/lib/input/sketch/helper/sketch_page.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:parabeac_core/input/helper/design_page.dart'; -import 'package:quick_log/quick_log.dart'; - -class SketchPage extends DesignPage { - @override - var log = Logger('Design Page Sketch'); - - SketchPage(String name, String id) - : super( - name: name, - id: id, - ); -} diff --git a/lib/input/sketch/helper/sketch_project.dart b/lib/input/sketch/helper/sketch_project.dart deleted file mode 100644 index 4db195ce..00000000 --- a/lib/input/sketch/helper/sketch_project.dart +++ /dev/null @@ -1,150 +0,0 @@ -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; -import 'package:parabeac_core/input/helper/design_project.dart'; -import 'package:parabeac_core/input/sketch/entities/documents/document.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/page.dart'; -import 'package:parabeac_core/input/sketch/entities/objects/foreign_symbol.dart'; -import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_page.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_screen.dart'; -import 'dart:convert'; -import 'package:archive/archive.dart'; -import 'package:parabeac_core/input/sketch/services/input_design.dart'; -import 'package:quick_log/quick_log.dart'; -import 'package:recase/recase.dart'; - -class SketchProject extends DesignProject { - @override - var log = Logger('SketchNodeTree'); - SketchPage rootScreen; - - @override - String projectName; - @override - bool debug = false; - - final InputDesignService _ids; - Archive _originalArchive; - final Map _pagesAndArtboards; - // Map to prevent name collisions - Map layerNames = {}; - - SketchProject(this._ids, this._pagesAndArtboards, this.projectName) { - id = _ids.documentFile['do_objectID']; - _originalArchive = _ids.archive; - miscPages.add(_setThirdPartySymbols()); - sharedStyles = _setSharedStyles(); - pages.addAll(_setConventionalPages(_pagesAndArtboards)); - if (debug) { - print(pages); - } - } - - List _setSharedStyles() { - try { - var sharedStyles = []; - var jsonData = _ids.documentFile; - var doc = Document.fromJson(jsonData); - if (doc.layerStyles != null) { - var LayerStyles = doc.layerStyles['objects'] ?? []; - for (var sharedStyle in LayerStyles) { - var layerStyle = SharedStyle.fromJson(sharedStyle); - layerStyle.name = GetUniqueLayerName(layerStyle.name.camelCase); - sharedStyles.add(layerStyle); - } - } - - if (doc.layerTextStyles != null) { - var LayerTextStyles = doc.layerTextStyles['objects'] ?? []; - - for (var sharedStyle in LayerTextStyles) { - var layerTextStyle = SharedStyle.fromJson(sharedStyle); - layerTextStyle.name = GetUniqueLayerName(layerTextStyle.name.camelCase); - sharedStyles.add(layerTextStyle); - } - } - - return sharedStyles; - } catch (e, stackTrace) { - MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); - log.error(e.toString()); - return null; - } - } - - SketchPage _setThirdPartySymbols() { - try { - var jsonData = _ids.documentFile; - var doc = Document.fromJson(jsonData); - var foreignLayers = doc.foreignSymbols ?? []; - var pg = SketchPage('third_party_widgets', jsonData['do_objectID']); - for (var layer in foreignLayers) { - pg.addScreen(SketchScreen( - layer.originalMaster, - layer.UUID, - '', - layer.originalMaster.type, - )); - } - return pg; - } catch (e, stackTrace) { - MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); - log.error(e.toString()); - return null; - } - } - - List _setConventionalPages(Map pagesAndArtboards) { - var sketchPages = []; - for (var entry in pagesAndArtboards.entries) { - var pageContent = - _originalArchive.findFile('pages/${entry.key}.json').content; - var jsonData = json.decode(utf8.decode(pageContent)); - - var pbdlPage = getPbdlPage(jsonData['do_objectID']); - if (pbdlPage != null && !(pbdlPage['convert'] ?? true)) { - continue; - } - - var pg = SketchPage( - jsonData['name'], jsonData['do_objectID']); // Sketch Node Holder - var node = Page.fromJson(jsonData); // Actual Sketch Node - - // Turn layers into PBNodes - for (var layer in node.children) { - var pbdlScreen = getPbdlScreen(pbdlPage, layer.UUID); - if (pbdlScreen != null && !(pbdlScreen['convert'] ?? true)) { - continue; - } - pg.addScreen(SketchScreen( - layer, - layer.UUID, - layer.name, - layer.type, - )); - } - sketchPages.add(pg); - } - return sketchPages; - } - - String GetUniqueLayerName(String layerStyleName) { - var name = PBInputFormatter.formatVariable(layerStyleName); - var count = 0; - if (layerNames.containsKey(name)) { - count = layerNames[name] + 1; - name += count.toString(); - } - - layerNames[name] = count; - - return name; - } - -} diff --git a/lib/input/sketch/helper/sketch_screen.dart b/lib/input/sketch/helper/sketch_screen.dart deleted file mode 100644 index 6ea044c1..00000000 --- a/lib/input/sketch/helper/sketch_screen.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/helper/design_screen.dart'; - -class SketchScreen extends DesignScreen { - SketchScreen( - DesignNode root, - String id, - String name, - String type, - ) : super( - designNode: root, - id: id, - name: name, - type: type, - ); -} diff --git a/lib/input/sketch/helper/symbol_node_mixin.dart b/lib/input/sketch/helper/symbol_node_mixin.dart deleted file mode 100644 index 42b45f5b..00000000 --- a/lib/input/sketch/helper/symbol_node_mixin.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'dart:core'; -import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/style/style.dart'; -import 'package:parabeac_core/input/sketch/entities/style/text_style.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; -import 'package:recase/recase.dart'; - -// both need to be global because a symbol instance could have multiple master symbols with name conflicts -Map SN_UUIDtoVarName = {}; -Map varNameCount = {}; - -mixin SymbolNodeMixin { - final Map typeToAbbreviation = { - TextStyle: 'ts', - String: 'str', - Style: 'sty', - InheritedBitmap: 'bm', - PBSharedInstanceIntermediateNode: 'sv', - }; - - // should have been a Map but iterate slowly through the list - String FindName(String uuid, List children, Type type) { - for (var child in children) { - if (child.UUID == uuid) { - var name = - ((typeToAbbreviation[type] ?? 'un') + ' ' + (child.name ?? 'var')) - .camelCase; - return name.replaceAll( - RegExp( - r'[^A-Za-z0-9_]', - ), - ''); - } else if (child is AbstractGroupLayer) { - var found = FindName(uuid, child.children, type); - if (found != null) { - return found; - } - } - } - // return null to indicate not found - return null; - } - - Map AddMasterSymbolOverrideName(String overrideName, List children) { - var varName; - var parmInfo = extractParameter(overrideName); - var uuid = parmInfo['uuid']; - - var nodeName = FindName(uuid, children, parmInfo['type']); - // only add names of our direct descendants - if (nodeName != null) { - // only increase count, make new varName if unique UUID - if (!SN_UUIDtoVarName.containsKey(overrideName)) { - var count = varNameCount[nodeName] ?? 0; - varName = nodeName; - varNameCount[nodeName] = count + 1; - // first one doesn't have appended number - if (count > 0) { - varName += count.toString(); - } - SN_UUIDtoVarName[overrideName] = varName; - } else { - varName = SN_UUIDtoVarName[overrideName]; - } - } - return {'name': varName, 'type': parmInfo['type'], 'uuid': uuid}; - } - - ///Extracting the UUID of the parameter either from the [SymbolInstance] - ///or the [SymbolMaster]. - ///The first element in the [List] is going to be the UUID, while - ///the second element is going to be the [Type]. - Map extractParameter(String overrideName) { - var properties = overrideName.split('_'); - assert(properties.length > 1, - 'The symbol ($overrideName) parameter does not contain sufficient data'); - var type, uuid = properties[0]; - - switch (properties[1]) { - case 'stringValue': - type = String; - break; - case 'symbolID': - type = PBSharedInstanceIntermediateNode; - break; - case 'image': - type = InheritedBitmap; - break; - case 'textStyle': - type = TextStyle; - break; - case 'layerStyle': - type = Style; - break; - default: - type = String; - } - - return {'type': type, 'uuid': uuid}; - } -} diff --git a/lib/input/sketch/services/input_design.dart b/lib/input/sketch/services/input_design.dart deleted file mode 100644 index 60f75e3b..00000000 --- a/lib/input/sketch/services/input_design.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/input/sketch/helper/sketch_page.dart'; -import 'package:path/path.dart'; -import 'package:archive/archive.dart'; -import 'package:path/path.dart' as p; - -/// Takes Initial Design File and puts it into a tree in object format. -/// Currently only supports Sketch Files -/// Class used to process the contents of a sketch file -class InputDesignService { - final String pathToFile; - final String IMAGE_DIR_NAME = 'images/'; - - String get filename => basename(File(pathToFile).path); - List sketchPages = []; - - Archive _archive; - - InputDesignService(this.pathToFile, {bool jsonOnly = false}) { - _archive = _unzip(File(pathToFile)); - if (!jsonOnly) { - setImageDir(); - } - } - - ///The archive of the unzipped sketch project - Archive get archive => _archive; - - ///The json-decoded meta.json file inside the sketch project - Map get metaFileJson { - final metaFile = archive.findFile('meta.json').content; - return json.decode(utf8.decode(metaFile)); - } - - Map get documentFile { - final doc_page = archive.findFile('document.json').content; - assert(doc_page != null, "Document page from Sketch doesn't exist."); - final doc_map = json.decode(utf8.decode(doc_page)); - return doc_map; - } - - ///Getting the images in the sketch file and adding them to the png folder. - void setImageDir() { - ///Creating the pngs folder, if it's already not there. - var pngsPath = p.join(MainInfo().pngPath); - Directory(pngsPath).createSync(recursive: true); - for (final file in archive) { - final fileName = file.name; - if (file.isFile && fileName.contains(IMAGE_DIR_NAME)) { - final data = file.content as List; - final name = fileName.replaceAll(IMAGE_DIR_NAME, ''); - File(p.join(pngsPath, name)).writeAsBytesSync(data); - } - } - } - - ///Unzips the file and returns the archive - Archive _unzip(File f) { - List bytes = f.readAsBytesSync(); - return ZipDecoder().decodeBytes(bytes); - } -} diff --git a/lib/input/sketch/services/positional_cleansing_service.dart b/lib/input/sketch/services/positional_cleansing_service.dart deleted file mode 100644 index 454e5854..00000000 --- a/lib/input/sketch/services/positional_cleansing_service.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/abstract_group_layer.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/artboard.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/group.dart'; - -import '../entities/layers/symbol_master.dart'; - -///Class for cleansing the positional data of the [DesignNode] -///TODO(Eddie): Abstract it, not only for Sketch node but potentially more design files. -class PositionalCleansingService { - ///Eliminating the offset of the nodes. NOTE: the only nodes that have an offset are [Artboard] and [Group] - DesignNode eliminateOffset(DesignNode rootNode) { - if (rootNode is Group || rootNode is Artboard || rootNode is SymbolMaster) { - _eliminateOffsetChildren( - (rootNode as AbstractGroupLayer).children, rootNode); - } - if (rootNode is AbstractGroupLayer) { - rootNode.children.map((layerNode) => eliminateOffset(layerNode)).toList(); - } - return rootNode; - } - - void _eliminateOffsetChildren(List children, DesignNode parent) => - children.forEach((child) { - child.boundaryRectangle.x = - (parent.boundaryRectangle.x + child.boundaryRectangle.x); - child.boundaryRectangle.y = - (parent.boundaryRectangle.y + child.boundaryRectangle.y); - }); -} diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index 6b2b48eb..7bddc9c6 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -33,4 +33,7 @@ class Flexible extends PBVisualIntermediateNode { generator = PBFlexibleGenerator(); this.child = child; } + + @override + PBIntermediateNode fromJson(Map json) => null; } diff --git a/lib/interpret_and_optimize/entities/alignments/injected_align.dart b/lib/interpret_and_optimize/entities/alignments/injected_align.dart new file mode 100644 index 00000000..b7fd2162 --- /dev/null +++ b/lib/interpret_and_optimize/entities/alignments/injected_align.dart @@ -0,0 +1,72 @@ +import 'package:parabeac_core/generation/generators/visual-widgets/pb_align_gen.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; + +class InjectedAlign extends PBVisualIntermediateNode + implements PBInjectedIntermediate { + double alignX; + double alignY; + + InjectedAlign(Point topLeftCorner, Point bottomRightCorner, + PBContext currentContext, String name) + : super(topLeftCorner, bottomRightCorner, currentContext, name) { + generator = PBAlignGenerator(); + } + + @override + void addChild(PBIntermediateNode node) { + if (child is TempGroupLayoutNode) { + child.addChild(node); + return; + } + // If there's multiple children add a temp group so that layout service lays the children out. + if (child != null) { + var temp = + TempGroupLayoutNode(currentContext: currentContext, name: node.name); + temp.addChild(child); + temp.addChild(node); + child = temp; + } + child = node; + } + + @override + void alignChild() { + var maxX = (topLeftCorner.x - bottomRightCorner.x).abs() - + (child.bottomRightCorner.x - child.topLeftCorner.x).abs(); + var parentCenterX = (topLeftCorner.x + bottomRightCorner.x) / 2; + var childCenterX = (child.topLeftCorner.x + child.bottomRightCorner.x) / 2; + var alignmentX = 0.0; + + if (maxX != 0.0) { + alignmentX = ((childCenterX - parentCenterX) / maxX) * 2; + } + + var parentCenterY = (topLeftCorner.y + bottomRightCorner.y) / 2; + var maxY = (topLeftCorner.y - bottomRightCorner.y).abs() - + (child.bottomRightCorner.y - child.topLeftCorner.y).abs(); + var childCenterY = (child.topLeftCorner.y + child.bottomRightCorner.y) / 2; + var alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; + + if (maxY != 0.0) { + alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; + } + + if (alignmentX.isNaN) { + alignmentX = 0; + } + if (alignmentY.isNaN) { + alignmentY = 0; + } + + alignX = alignmentX.toDouble(); + alignY = alignmentY.toDouble(); + } + + @override + PBIntermediateNode fromJson(Map json) => null; +} diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index e70365ef..44abfe46 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -27,6 +27,8 @@ class InjectedPositioned extends PBIntermediateNode generator = PBPositionedGenerator(overrideChildDim: true); } + @override + PBIntermediateNode fromJson(Map json) => null; } /// Class to help us communicate and manipulate positioning values. diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index a86a7acc..1df794e4 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -72,4 +72,6 @@ class Padding extends PBVisualIntermediateNode { bottom = bottom < 0.01 ? 0.0 : bottom; } } + @override + PBIntermediateNode fromJson(Map json) => null; } diff --git a/lib/interpret_and_optimize/entities/alignments/spacer.dart b/lib/interpret_and_optimize/entities/alignments/spacer.dart index 08a8d5ab..98cbaad7 100644 --- a/lib/interpret_and_optimize/entities/alignments/spacer.dart +++ b/lib/interpret_and_optimize/entities/alignments/spacer.dart @@ -18,4 +18,7 @@ class Spacer extends PBVisualIntermediateNode { UUID: UUID) { generator = PBSpacerGenerator(); } + + @override + PBIntermediateNode fromJson(Map json) => null; } diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index 38723fb5..ee19908c 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -1,8 +1,6 @@ import 'dart:math'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/image.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; @@ -11,58 +9,81 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; // import 'dart:math'; import 'package:quick_log/quick_log.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; -class InheritedBitmap extends PBVisualIntermediateNode - implements PBInheritedIntermediate { - @override - final originalRef; +part 'inherited_bitmap.g.dart'; +@JsonSerializable() +class InheritedBitmap extends PBVisualIntermediateNode + implements PBInheritedIntermediate, IntermediateNodeFactory { @override + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; @override ChildrenStrategy childrenStrategy = NoChildStrategy(); + @JsonKey(name: 'imageReference') String referenceImage; - InheritedBitmap(this.originalRef, String name, - {PBContext currentContext, - this.referenceImage, - PBIntermediateConstraints constraints}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height), - currentContext, - name, - UUID: originalRef.UUID ?? '', - constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBBitmapGenerator(); + @override + @JsonKey() + String type = 'image'; + + @override + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + + @override + String UUID; - if (originalRef.name == null || - (originalRef as Image).imageReference == null) { - logger.debug('NULL BITMAP'); - } - name = (originalRef as Image).imageReference; - size = { - 'width': originalRef.boundaryRectangle.width, - 'height': originalRef.boundaryRectangle.height - }; - referenceImage = (originalRef as Image).imageReference; - ImageReferenceStorage().addReference( - originalRef.UUID, '${MainInfo().outputPath}assets/images'); + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + + @override + @JsonKey(ignore: true) + PBContext currentContext; + + @override + @JsonKey(ignore: true) + Map originalRef; + + InheritedBitmap({ + this.originalRef, + String name, + this.currentContext, + this.referenceImage, + this.bottomRightCorner, + this.topLeftCorner, + this.UUID, + this.prototypeNode, + this.size, + }) : super(topLeftCorner, bottomRightCorner, currentContext, name, + UUID: UUID ?? '') { + generator = PBBitmapGenerator(); + ImageReferenceStorage() + .addReference(UUID, '${MainInfo().outputPath}assets/images'); } + static PBIntermediateNode fromJson(Map json) => + _$InheritedBitmapFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + @override + PBIntermediateNode createIntermediateNode(Map json) => + (InheritedBitmap.fromJson(json) as InheritedBitmap)..originalRef = json; } diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart new file mode 100644 index 00000000..b6bca16c --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart @@ -0,0 +1,47 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_bitmap.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedBitmap _$InheritedBitmapFromJson(Map json) { + return InheritedBitmap( + name: json['name'] as String, + referenceImage: json['imageReference'] as String, + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedBitmapToJson(InheritedBitmap instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'imageReference': instance.referenceImage, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 3ceacf29..c94e20d5 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -1,25 +1,47 @@ +<<<<<<< HEAD import 'dart:math'; import 'package:parabeac_core/design_logic/design_node.dart'; +======= +>>>>>>> origin/feat/pbdl-interpret import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/intermediate_border_info.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +<<<<<<< HEAD import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +======= +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; +>>>>>>> origin/feat/pbdl-interpret + +part 'inherited_circle.g.dart'; +@JsonSerializable() class InheritedCircle extends PBVisualIntermediateNode - implements PBInheritedIntermediate { + implements PBInheritedIntermediate, IntermediateNodeFactory { @override - final originalRef; + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') + PrototypeNode prototypeNode; @override - PrototypeNode prototypeNode; + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; @override +<<<<<<< HEAD ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); InheritedCircle(this.originalRef, Point bottomRightCorner, @@ -31,13 +53,91 @@ class InheritedCircle extends PBVisualIntermediateNode prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } generator = PBBitmapGenerator(); +======= + @JsonKey() + String type = 'circle'; +>>>>>>> origin/feat/pbdl-interpret - size = { - 'width': originalRef.boundaryRectangle.width, - 'height': originalRef.boundaryRectangle.height, - }; + @override + String UUID; + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + +<<<<<<< HEAD auxiliaryData.borderInfo = {}; auxiliaryData.borderInfo['shape'] = 'circle'; +======= + @override + @JsonKey(ignore: true) + PBContext currentContext; + + @override + @JsonKey(ignore: true) + Map originalRef; + + InheritedCircle({ + this.originalRef, + this.bottomRightCorner, + this.topLeftCorner, + String name, + this.currentContext, + Point alignX, + Point alignY, + this.UUID, + this.size, + this.prototypeNode, + }) : super(topLeftCorner, bottomRightCorner, currentContext, name, + UUID: UUID ?? '') { + generator = PBBitmapGenerator(); + + auxiliaryData.borderInfo = IntermediateBorderInfo(); + auxiliaryData.borderInfo.shape = 'circle'; + auxiliaryData.alignment = alignX != null && alignY != null + ? {'alignX': alignX, 'alignY': alignY} + : null; + } + + @override + void addChild(PBIntermediateNode node) { + if (child is TempGroupLayoutNode) { + child.addChild(node); + return; + } + // If there's multiple children add a temp group so that layout service lays the children out. + if (child != null) { + var temp = TempGroupLayoutNode( + currentContext: currentContext, + name: node.name, + ); + temp.addChild(child); + temp.addChild(node); + child = temp; + } + child = node; } + + /// Should add positional info ONLY to parent node. This should only be sent here if the parent and child node is only one-to-one. + /// + /// alignCenterX/y = ((childCenter - parentCenter) / max) if > 0.5 subtract 0.5 if less than 0.5 multiply times -1 + @override + void alignChild() { + var align = + InjectedAlign(topLeftCorner, bottomRightCorner, currentContext, ''); + align.addChild(child); + align.alignChild(); + child = align; +>>>>>>> origin/feat/pbdl-interpret + } + + static PBIntermediateNode fromJson(Map json) => + _$InheritedCircleFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InheritedCircle.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_circle.g.dart b/lib/interpret_and_optimize/entities/inherited_circle.g.dart new file mode 100644 index 00000000..c699c164 --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_circle.g.dart @@ -0,0 +1,45 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_circle.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedCircle _$InheritedCircleFromJson(Map json) { + return InheritedCircle( + name: json['name'] as String, + UUID: json['UUID'] as String, + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedCircleToJson(InheritedCircle instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index e1324b72..76deac92 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -1,7 +1,5 @@ import 'dart:math'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; @@ -14,88 +12,95 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; -class InheritedContainer extends PBVisualIntermediateNode - with PBColorMixin - implements PBInheritedIntermediate { - @override - final originalRef; +part 'inherited_container.g.dart'; +@JsonSerializable() +class InheritedContainer extends PBVisualIntermediateNode + implements PBInheritedIntermediate, IntermediateNodeFactory { @override + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; + @JsonKey(defaultValue: true) bool isBackgroundVisible = true; @override - ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + + ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); /// TODO: switch to padding @override AlignStrategy alignStrategy = NoAlignment(); - InheritedContainer(this.originalRef, Point topLeftCorner, - Point bottomRightCorner, String name, - {double alignX, - double alignY, - PBContext currentContext, - Map borderInfo, - this.isBackgroundVisible = true, - PBIntermediateConstraints constraints}) - : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: originalRef.UUID ?? '', constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBContainerGenerator(); - borderInfo ??= {}; + @override + @JsonKey() + String type = 'rectangle'; - size = { - 'width': originalRef.boundaryRectangle.width, - 'height': originalRef.boundaryRectangle.height, - }; + @override + String UUID; - // have to save this in case it is overridden - auxiliaryData.style = originalRef.style; + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; - if (originalRef.style != null && originalRef.style.fills.isNotEmpty) { - for (var fill in originalRef.style.fills) { - if (fill.isEnabled) { - auxiliaryData.color = toHex(fill.color); - // use the first one found. - break; - } - } - } + @override + @JsonKey(ignore: true) + PBContext currentContext; - auxiliaryData.borderInfo = borderInfo; + @override + @JsonKey(ignore: true) + Map originalRef; + + @override + @JsonKey(ignore: true) + List get children => null; + + InheritedContainer({ + this.originalRef, + this.topLeftCorner, + this.bottomRightCorner, + String name, + double alignX, + double alignY, + this.currentContext, + this.isBackgroundVisible = true, + this.UUID, + this.size, + this.prototypeNode, + }) : super(topLeftCorner, bottomRightCorner, currentContext, name, + UUID: UUID ?? '') { + generator = PBContainerGenerator(); - assert(originalRef != null, - 'A null original reference was sent to an PBInheritedIntermediate Node'); + auxiliaryData.alignment = alignX != null && alignY != null + ? {'alignX': alignX, 'alignY': alignY} + : null; } - // @override - // void alignChild() { - // if (child != null) { - // /// Refactor to child.constraints != null - // if (child is! InheritedText) { - // // var left = (child.topLeftCorner.x - topLeftCorner.x).abs() ?? 0.0; - // // var right = - // // (bottomRightCorner.x - child.bottomRightCorner.x).abs() ?? 0.0; - // // var top = (child.topLeftCorner.y - topLeftCorner.y).abs() ?? 0.0; - // // var bottom = - // // (bottomRightCorner.y - child.bottomRightCorner.y).abs() ?? 0.0; - // // var padding = Padding('', child.constraints, - // // left: left, - // // right: right, - // // top: top, - // // bottom: bottom, - // // topLeftCorner: topLeftCorner, - // // bottomRightCorner: bottomRightCorner, - // // currentContext: currentContext); - // // padding.addChild(child); - // // child = padding; - // } - // } - // } + static PBIntermediateNode fromJson(Map json) { + var container = _$InheritedContainerFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + container.mapRawChildren(json); + container.auxiliaryData.borderInfo.borderRadius = json['fixedRadius']; + + return container; + } + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InheritedContainer.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_container.g.dart b/lib/interpret_and_optimize/entities/inherited_container.g.dart new file mode 100644 index 00000000..4817ec21 --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_container.g.dart @@ -0,0 +1,41 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_container.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedContainer _$InheritedContainerFromJson(Map json) { + return InheritedContainer( + name: json['name'] as String, + isBackgroundVisible: json['isBackgroundVisible'] as bool ?? true, + UUID: json['UUID'] as String, + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + ) + ..subsemantic = json['subsemantic'] as String + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedContainerToJson(InheritedContainer instance) => + { + 'subsemantic': instance.subsemantic, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'isBackgroundVisible': instance.isBackgroundVisible, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index 595cc37e..6b7025fb 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -2,7 +2,6 @@ import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; @@ -12,51 +11,77 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:quick_log/quick_log.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; +part 'inherited_oval.g.dart'; + +@JsonSerializable() class InheritedOval extends PBVisualIntermediateNode - implements PBInheritedIntermediate { + implements PBInheritedIntermediate, IntermediateNodeFactory { + @JsonKey(ignore: true) + var log = Logger('Layout Generation Service'); + @override - var originalRef; + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') + PrototypeNode prototypeNode; @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; @override - PrototypeNode prototypeNode; + @JsonKey() + String type = 'oval'; - InheritedOval(this.originalRef, String name, - {Uint8List image, - PBContext currentContext, - PBIntermediateConstraints constraints}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height), - currentContext, - name, - UUID: originalRef.UUID ?? '', - constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBBitmapGenerator(); + @override + String UUID; - size = { - 'width': originalRef.boundaryRectangle.width, - 'height': originalRef.boundaryRectangle.height - }; + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; - name = originalRef.name; + @override + @JsonKey(ignore: true) + PBContext currentContext; + + @override + @JsonKey(ignore: true) + Map originalRef; + + InheritedOval({ + this.originalRef, + String name, + Uint8List image, + this.currentContext, + this.topLeftCorner, + this.bottomRightCorner, + this.UUID, + this.prototypeNode, + this.size, + }) : super(topLeftCorner, bottomRightCorner, currentContext, name, + UUID: UUID ?? '') { + generator = PBBitmapGenerator(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); } + static PBIntermediateNode fromJson(Map json) => + _$InheritedOvalFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InheritedOval.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_oval.g.dart b/lib/interpret_and_optimize/entities/inherited_oval.g.dart new file mode 100644 index 00000000..130bbfe8 --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_oval.g.dart @@ -0,0 +1,45 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_oval.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedOval _$InheritedOvalFromJson(Map json) { + return InheritedOval( + name: json['name'] as String, + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedOvalToJson(InheritedOval instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index a3c6eab8..59a41d3c 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -1,7 +1,6 @@ import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; @@ -14,47 +13,79 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; + +part 'inherited_polygon.g.dart'; +@JsonSerializable() class InheritedPolygon extends PBVisualIntermediateNode - implements PBInheritedIntermediate { + implements PBInheritedIntermediate, IntermediateNodeFactory { @override - var originalRef; + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') + PrototypeNode prototypeNode; @override - PrototypeNode prototypeNode; + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + + ChildrenStrategy childrenStrategy = NoChildStrategy(); @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - - InheritedPolygon(this.originalRef, String name, - {Uint8List image, - PBContext currentContext, - PBIntermediateConstraints constraints}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height), - currentContext, - name, - UUID: originalRef.UUID ?? '', - constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBBitmapGenerator(); + @JsonKey() + String type = 'polygon'; + + @override + String UUID; - size = { - 'width': originalRef.boundaryRectangle.width, - 'height': originalRef.boundaryRectangle.height - }; - name = originalRef.name; + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + @override + @JsonKey(ignore: true) + PBContext currentContext; + + @override + @JsonKey(ignore: true) + Map originalRef; + + InheritedPolygon({ + this.originalRef, + name, + Uint8List image, + this.currentContext, + this.UUID, + this.topLeftCorner, + this.bottomRightCorner, + this.prototypeNode, + this.size, + }) : super( + topLeftCorner, + bottomRightCorner, + currentContext, + name, + UUID: UUID ?? '', + ) { + generator = PBBitmapGenerator(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); } + static PBIntermediateNode fromJson(Map json) => + _$InheritedPolygonFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InheritedPolygon.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart new file mode 100644 index 00000000..31e1c7db --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart @@ -0,0 +1,45 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_polygon.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedPolygon _$InheritedPolygonFromJson(Map json) { + return InheritedPolygon( + name: json['name'], + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedPolygonToJson(InheritedPolygon instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index acc41895..d898d4b1 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -1,6 +1,4 @@ import 'dart:math'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/eggs/injected_app_bar.dart'; import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; @@ -13,25 +11,50 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attr import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:json_annotation/json_annotation.dart'; -import 'interfaces/pb_inherited_intermediate.dart'; +part 'inherited_scaffold.g.dart'; +@JsonSerializable() class InheritedScaffold extends PBVisualIntermediateNode with PBColorMixin - implements PBInheritedIntermediate { - @override - var originalRef; + implements + /* with GeneratePBTree */ /* PropertySearchable,*/ PBInheritedIntermediate, + IntermediateNodeFactory { @override + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; + @JsonKey(defaultValue: false, name: 'isFlowHome') bool isHomeScreen = false; + AlignStrategy alignStrategy = NoAlignment();//PaddingAlignment(); + @override + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + + @override + @JsonKey() + String type = 'artboard'; @override - AlignStrategy alignStrategy = NoAlignment();//PaddingAlignment(); + String UUID; @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + + @override + @JsonKey(ignore: true) + PBContext currentContext; + + @override + @JsonKey(ignore: true) PBIntermediateNode get child => getAttributeNamed('body')?.attributeNode; @override @@ -51,34 +74,37 @@ class InheritedScaffold extends PBVisualIntermediateNode } } - InheritedScaffold(this.originalRef, - {Point topLeftCorner, - Point bottomRightCorner, - String name, - PBContext currentContext, - this.isHomeScreen}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height), - currentContext, - name, - UUID: originalRef.UUID ?? '') { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } + @override + @JsonKey(ignore: true) + List get children => super.children; + + @override + @JsonKey(ignore: true) + Map originalRef; + + InheritedScaffold({ + this.originalRef, + this.topLeftCorner, + this.bottomRightCorner, + String name, + this.currentContext, + this.isHomeScreen, + this.UUID, + this.prototypeNode, + this.size, + }) : super( + topLeftCorner, + bottomRightCorner, + currentContext, + name, + UUID: UUID ?? '', + ) { this.name = name ?.replaceAll(RegExp(r'[\W]'), '') ?.replaceFirst(RegExp(r'^([\d]|_)+'), ''); generator = PBScaffoldGenerator(); - auxiliaryData.color = toHex(originalRef.backgroundColor); - // Add body attribute addAttribute(PBAttribute('body')); } @@ -94,13 +120,13 @@ class InheritedScaffold extends PBVisualIntermediateNode print('object'); } if (node is PBSharedInstanceIntermediateNode) { - if (node.originalRef.name.contains('')) { + if (node.name.contains('')) { addAttribute(PBAttribute('appBar', attributeNodes: [node])); currentContext.canvasTLC = Point(currentContext.canvasTLC.x, node.bottomRightCorner.y); return; } - if (node.originalRef.name.contains('')) { + if (node.name.contains('')) { addAttribute( PBAttribute('bottomNavigationBar', attributeNodes: [node])); return; @@ -121,6 +147,14 @@ class InheritedScaffold extends PBVisualIntermediateNode if (child is TempGroupLayoutNode) { child.addChild(node); return; + } + // If there's multiple children add a temp group so that layout service lays the children out. + if (child != null) { + var temp = + TempGroupLayoutNode(currentContext: currentContext, name: node.name); + temp.addChild(child); + temp.addChild(node); + child = temp; } else { if (child != null) { child.addChild(node); @@ -137,4 +171,19 @@ class InheritedScaffold extends PBVisualIntermediateNode } } } + + static PBIntermediateNode fromJson(Map json) { + var artboard = _$InheritedScaffoldFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + //Map artboard children by calling `addChild` method + artboard.mapRawChildren(json); + return artboard; + } + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InheritedScaffold.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart new file mode 100644 index 00000000..1af175cf --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart @@ -0,0 +1,37 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_scaffold.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedScaffold _$InheritedScaffoldFromJson(Map json) { + return InheritedScaffold( + name: json['name'] as String, + isHomeScreen: json['isFlowHome'] as bool ?? false, + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedScaffoldToJson(InheritedScaffold instance) => + { + 'subsemantic': instance.subsemantic, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'isFlowHome': instance.isHomeScreen, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index e0bb287d..de81a4d6 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -1,8 +1,6 @@ import 'dart:math'; import 'dart:typed_data'; - import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; @@ -14,48 +12,88 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; + +part 'inherited_shape_group.g.dart'; +@JsonSerializable() class InheritedShapeGroup extends PBVisualIntermediateNode - implements PBInheritedIntermediate { + implements PBInheritedIntermediate, IntermediateNodeFactory { @override - var originalRef; + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') + PrototypeNode prototypeNode; @override - PrototypeNode prototypeNode; + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + ChildrenStrategy childrenStrategy = NoChildStrategy(); @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - - InheritedShapeGroup(this.originalRef, String name, - {Uint8List image, - PBContext currentContext, - PBIntermediateConstraints constraints}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height), - currentContext, - name, - UUID: originalRef.UUID ?? '', - constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBBitmapGenerator(); + @JsonKey() + String type = 'image'; + + @override + String UUID; - size = { - 'width': originalRef.boundaryRectangle.width, - 'height': originalRef.boundaryRectangle.height - }; + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; - name = originalRef.name; + @override + @JsonKey(ignore: true) + PBContext currentContext; + + @override + @JsonKey(ignore: true) + Map originalRef; + + @override + @JsonKey(ignore: true) + List get children => super.children; + + InheritedShapeGroup({ + this.originalRef, + String name, + Uint8List image, + this.currentContext, + this.topLeftCorner, + this.bottomRightCorner, + this.UUID, + this.prototypeNode, + this.size, + }) : super( + topLeftCorner, + bottomRightCorner, + currentContext, + name, + UUID: UUID ?? '', + ) { + generator = PBBitmapGenerator(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); } + static PBIntermediateNode fromJson(Map json) { + var group = _$InheritedShapeGroupFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + group.mapRawChildren(json); + + return group; + } + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InheritedShapeGroup.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart new file mode 100644 index 00000000..a35801e6 --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart @@ -0,0 +1,40 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_shape_group.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { + return InheritedShapeGroup( + name: json['name'] as String, + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedShapeGroupToJson( + InheritedShapeGroup instance) => + { + 'subsemantic': instance.subsemantic, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 490e116f..54b48483 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -2,12 +2,8 @@ import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; -import 'package:parabeac_core/generation/generators/visual-widgets/pb_container_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/shape_path.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -17,45 +13,66 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; + +part 'inherited_shape_path.g.dart'; +@JsonSerializable() class InheritedShapePath extends PBVisualIntermediateNode - with PBColorMixin - implements PBInheritedIntermediate { - @override - var originalRef; + implements PBInheritedIntermediate, IntermediateNodeFactory { @override + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; + ChildrenStrategy childrenStrategy = NoChildStrategy(); + @override + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - - InheritedShapePath(this.originalRef, String name, - {Uint8List image, - PBContext currentContext, - PBIntermediateConstraints constraints}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height), - currentContext, - name, - UUID: originalRef.UUID ?? '', - constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBBitmapGenerator(); + @JsonKey() + String type = 'image'; + + @override + String UUID; + + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; - size = { - 'width': originalRef.boundaryRectangle.width, - 'height': originalRef.boundaryRectangle.height - }; + @override + @JsonKey(ignore: true) + PBContext currentContext; - name = originalRef.name; + @override + @JsonKey(ignore: true) + Map originalRef; + + InheritedShapePath({ + this.originalRef, + String name, + Uint8List image, + this.currentContext, + this.topLeftCorner, + this.bottomRightCorner, + this.prototypeNode, + this.UUID, + this.size, + }) : super( + topLeftCorner, + bottomRightCorner, + currentContext, + name, + UUID: UUID ?? '', + ) { + generator = PBBitmapGenerator(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); @@ -65,29 +82,29 @@ class InheritedShapePath extends PBVisualIntermediateNode } void _detectLineAsContainer() { - var path = (originalRef as ShapePath); - // Possible vertical or horizontal point - if (path.points.length == 2) { - //Parse the points - var p1Str = path.points[0]['point'] - .toString() - .replaceAll('{', '') - .replaceAll('}', '') - .split(','); - var p2Str = path.points[1]['point'] - .toString() - .replaceAll('{', '') - .replaceAll('}', '') - .split(','); - - var p1 = Point(double.parse(p1Str[0]), double.parse(p1Str[1])); - var p2 = Point(double.parse(p2Str[0]), double.parse(p2Str[1])); - - if (_isEdgeAdjacent(p1, p2)) { - generator = PBContainerGenerator(); - auxiliaryData.color = toHex(originalRef.style.borders[0].color); - } - } + // var path = (originalRef as ShapePath); + // // Possible vertical or horizontal point + // if (path.points.length == 2) { + // //Parse the points + // var p1Str = path.points[0]['point'] + // .toString() + // .replaceAll('{', '') + // .replaceAll('}', '') + // .split(','); + // var p2Str = path.points[1]['point'] + // .toString() + // .replaceAll('{', '') + // .replaceAll('}', '') + // .split(','); + + // var p1 = Point(double.parse(p1Str[0]), double.parse(p1Str[1])); + // var p2 = Point(double.parse(p2Str[0]), double.parse(p2Str[1])); + + // if (_isEdgeAdjacent(p1, p2)) { + // generator = PBContainerGenerator(); + // auxiliaryData.color = toHex(originalRef.style.borders[0].color); + // } + // } } /// Returns true if [p1] and [p2] form @@ -101,4 +118,14 @@ class InheritedShapePath extends PBVisualIntermediateNode return isVertical || isHorizontal; } + + static PBIntermediateNode fromJson(Map json) => + _$InheritedShapePathFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InheritedShapePath.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart new file mode 100644 index 00000000..6890d5e0 --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart @@ -0,0 +1,45 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_shape_path.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedShapePath _$InheritedShapePathFromJson(Map json) { + return InheritedShapePath( + name: json['name'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + UUID: json['UUID'] as String, + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedShapePathToJson(InheritedShapePath instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index 1fbdf328..c828706d 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -1,7 +1,6 @@ import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; @@ -9,17 +8,32 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +<<<<<<< HEAD import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +======= +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; +>>>>>>> origin/feat/pbdl-interpret + +part 'inherited_star.g.dart'; +@JsonSerializable() class InheritedStar extends PBVisualIntermediateNode - implements PBInheritedIntermediate { + implements PBInheritedIntermediate, IntermediateNodeFactory { @override - var originalRef; + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') + PrototypeNode prototypeNode; @override +<<<<<<< HEAD PrototypeNode prototypeNode; @override @@ -45,16 +59,82 @@ class InheritedStar extends PBVisualIntermediateNode prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); } generator = PBBitmapGenerator(); +======= + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + + @override + @JsonKey() + String type = 'star'; + + @override + String UUID; +>>>>>>> origin/feat/pbdl-interpret + + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + + @override + @JsonKey(ignore: true) + PBContext currentContext; - size = { - 'width': originalRef.boundaryRectangle.width, - 'height': originalRef.boundaryRectangle.height - }; + @override + @JsonKey(ignore: true) + Map originalRef; - name = originalRef.name; + InheritedStar({ + this.originalRef, + name, + Uint8List image, + this.currentContext, + this.UUID, + this.topLeftCorner, + this.bottomRightCorner, + this.prototypeNode, + this.size, + }) : super( + topLeftCorner, + bottomRightCorner, + currentContext, + name, + UUID: UUID ?? '', + ) { + generator = PBBitmapGenerator(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); } +<<<<<<< HEAD +======= + @override + void addChild(PBIntermediateNode node) { + // Hopefully we converted the SVG correctly. Most likely this will get called to add the shapes but this is unnecessary. + if (node is InheritedShapePath) { + return; + } + assert(false, + 'Child with type ${node.runtimeType} could not be added as a child.'); + return; + } + + @override + void alignChild() { + // Images don't have children. + } + + static PBIntermediateNode fromJson(Map json) => + _$InheritedStarFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InheritedStar.fromJson(json); +>>>>>>> origin/feat/pbdl-interpret } diff --git a/lib/interpret_and_optimize/entities/inherited_star.g.dart b/lib/interpret_and_optimize/entities/inherited_star.g.dart new file mode 100644 index 00000000..8a8a81ae --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_star.g.dart @@ -0,0 +1,45 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_star.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedStar _$InheritedStarFromJson(Map json) { + return InheritedStar( + name: json['name'], + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedStarToJson(InheritedStar instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index d6baf860..dbc267f2 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -1,9 +1,7 @@ import 'dart:math'; -import 'package:parabeac_core/design_logic/color.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/text.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_text_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; @@ -11,74 +9,165 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; + +part 'inherited_text.g.dart'; +@JsonSerializable() class InheritedText extends PBVisualIntermediateNode - with PBColorMixin - implements PBInheritedIntermediate { + implements PBInheritedIntermediate, IntermediateNodeFactory { ///For the generator to strip out the quotation marks. + @JsonKey(defaultValue: false) bool isTextParameter = false; @override ChildrenStrategy childrenStrategy = NoChildStrategy(); @override - var originalRef; - - @override + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; + @JsonKey(ignore: true) num alignmenttype; + @override + @JsonKey() + String type = 'text'; + + @override + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + + @override + String UUID; + + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + + @override + @JsonKey(ignore: true) + PBContext currentContext; + + @JsonKey(name: 'content') String text; + @JsonKey(ignore: true) num fontSize; + @JsonKey(ignore: true) String fontName; + @JsonKey(ignore: true) String fontWeight; // one of the w100-w900 weights + @JsonKey(ignore: true) String fontStyle; // normal, or italic + @JsonKey(ignore: true) String textAlignment; + @JsonKey(ignore: true) num letterSpacing; - InheritedText(this.originalRef, String name, {PBContext currentContext}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height), - currentContext, - name, - UUID: originalRef.UUID ?? '') { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBTextGen(); + @override + @JsonKey(ignore: true) + Map originalRef; - text = (originalRef as Text).content; - if (text.contains('\$')) { + InheritedText({ + this.originalRef, + name, + this.currentContext, + this.topLeftCorner, + this.bottomRightCorner, + this.UUID, + this.size, + this.alignmenttype, + this.fontName, + this.fontSize, + this.fontStyle, + this.fontWeight, + this.isTextParameter, + this.letterSpacing, + this.prototypeNode, + this.text, + this.textAlignment, + }) : super(topLeftCorner, bottomRightCorner, currentContext, name, + UUID: UUID ?? '') { + generator = PBTextGen(); + if (text?.contains('\$') ?? false) { text = _sanitizeText(text); } - fontSize = originalRef.style.textStyle.fontDescriptor.fontSize; - auxiliaryData.color = toHex(originalRef.style.textStyle.fontColor); - fontName = originalRef.style.textStyle.fontDescriptor.fontName; - fontWeight = originalRef.style.textStyle.fontDescriptor.fontWeight; - fontStyle = originalRef.style.textStyle.fontDescriptor.fontStyle; - letterSpacing = originalRef.style.textStyle.fontDescriptor.letterSpacing; - - alignmenttype = originalRef.style.textStyle.paragraphStyle.alignment; - if (alignmenttype == 0) { - textAlignment = 'left'; - } else if (alignmenttype == 1) { - textAlignment = 'right'; - } else if (alignmenttype == 2) { - textAlignment = 'center'; - } else if (alignmenttype == 3) { - textAlignment = 'justify'; - } } String _sanitizeText(String text) { return text.replaceAll('\$', '\\\$'); } + static PBIntermediateNode fromJson(Map json) => + _$InheritedTextFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json + ..fontSize = InheritedTextPBDLHelper.fontSizeFromJson(json) + ..fontName = InheritedTextPBDLHelper.fontNameFromJson(json) + ..fontWeight = InheritedTextPBDLHelper.fontWeightFromJson(json) + ..fontStyle = InheritedTextPBDLHelper.fontStyleFromJson(json) + ..textAlignment = InheritedTextPBDLHelper.textAlignmentFromJson(json) + ..letterSpacing = InheritedTextPBDLHelper.letterSpacingFromJson(json) + ..auxiliaryData.color = PBColor.fromJson(json['style']['textStyle']['fontColor']); + + @override + PBIntermediateNode createIntermediateNode(Map json) { + var inheritedText = InheritedText.fromJson(json); + // Return an [InheritedContainer] that wraps this text + return InheritedContainer( + UUID: inheritedText.UUID, + topLeftCorner: inheritedText.topLeftCorner, + bottomRightCorner: inheritedText.bottomRightCorner, + name: inheritedText.name, + currentContext: inheritedText.currentContext, + size: inheritedText.size, + originalRef: json, + )..addChild(inheritedText); + } +} + +class InheritedTextPBDLHelper { + static num fontSizeFromJson(Map json) => + _fontDescriptor(json)['fontSize']; + + static String fontNameFromJson(Map json) => + _fontDescriptor(json)['fontName']; + + static String fontWeightFromJson(Map json) => + _fontDescriptor(json)['fontWeight']; + + static String fontStyleFromJson(Map json) => + _fontDescriptor(json)['fontStyle']; + + static String textAlignmentFromJson(Map json) { + var alignmenttype = _textStyle(json)['paragraphStyle']['alignment'] ?? 0; + switch (alignmenttype) { + case 1: + return 'right'; + case 2: + return 'center'; + case 3: + return 'justify'; + default: + return 'left'; + } + } + + static num letterSpacingFromJson(Map json) => + _fontDescriptor(json)['letterSpacing']; + + static Map _fontDescriptor(Map json) => + _textStyle(json)['fontDescriptor']; + + static Map _textStyle(Map json) => + json['style']['textStyle']; } diff --git a/lib/interpret_and_optimize/entities/inherited_text.g.dart b/lib/interpret_and_optimize/entities/inherited_text.g.dart new file mode 100644 index 00000000..15daec4b --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_text.g.dart @@ -0,0 +1,49 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_text.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedText _$InheritedTextFromJson(Map json) { + return InheritedText( + name: json['name'], + UUID: json['UUID'] as String, + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + isTextParameter: json['isTextParameter'] as bool ?? false, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + text: json['content'] as String, + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedTextToJson(InheritedText instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'isTextParameter': instance.isTextParameter, + 'prototypeNodeUUID': instance.prototypeNode, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + 'content': instance.text, + }; diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 759d33d3..8561e8d6 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -1,7 +1,6 @@ import 'dart:math'; import 'dart:typed_data'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; @@ -14,48 +13,78 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; +part 'inherited_triangle.g.dart'; + +@JsonSerializable() class InheritedTriangle extends PBVisualIntermediateNode - implements PBInheritedIntermediate { + implements PBInheritedIntermediate, IntermediateNodeFactory { @override - var originalRef; + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') + PrototypeNode prototypeNode; @override - PrototypeNode prototypeNode; + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + ChildrenStrategy childrenStrategy = NoChildStrategy(); + @override + @JsonKey() + String type = 'triangle'; @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - - InheritedTriangle(this.originalRef, String name, - {Uint8List image, - PBContext currentContext, - PBIntermediateConstraints constraints}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height), - currentContext, - name, - UUID: originalRef.UUID ?? '', - constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBBitmapGenerator(); + String UUID; - size = { - 'width': originalRef.boundaryRectangle.width, - 'height': originalRef.boundaryRectangle.height - }; + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + + @override + @JsonKey(ignore: true) + PBContext currentContext; + + @override + @JsonKey(ignore: true) + Map originalRef; - name = originalRef.name; + InheritedTriangle({ + this.originalRef, + String name, + Uint8List image, + this.currentContext, + this.topLeftCorner, + this.bottomRightCorner, + this.UUID, + this.prototypeNode, + this.size, + }) : super( + topLeftCorner, + bottomRightCorner, + currentContext, + name, + UUID: UUID ?? '', + ) { + generator = PBBitmapGenerator(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); } + static PBIntermediateNode fromJson(Map json) => + _$InheritedTriangleFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InheritedTriangle.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart new file mode 100644 index 00000000..7039ebf0 --- /dev/null +++ b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart @@ -0,0 +1,45 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inherited_triangle.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InheritedTriangle _$InheritedTriangleFromJson(Map json) { + return InheritedTriangle( + name: json['name'] as String, + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$InheritedTriangleToJson(InheritedTriangle instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index d6a62363..dda2d78c 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -12,28 +12,64 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; + +part 'injected_container.g.dart'; +@JsonSerializable() class InjectedContainer extends PBVisualIntermediateNode - implements PBInjectedIntermediate, PrototypeEnable { + implements + PBInjectedIntermediate, + PrototypeEnable, + IntermediateNodeFactory { @override + @JsonKey(fromJson: PrototypeNode.prototypeNodeFromJson) PrototypeNode prototypeNode; + ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); + @override + @JsonKey(fromJson: Point.topLeftFromJson) + Point topLeftCorner; + @override + @JsonKey(fromJson: Point.bottomRightFromJson) + Point bottomRightCorner; @override - ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); + @JsonKey() + String type = 'injected_container'; @override - AlignStrategy alignStrategy = NoAlignment();//PaddingAlignment(); + String UUID; - InjectedContainer( - Point bottomRightCorner, - Point topLeftCorner, + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson) + Map size; + + @override + @JsonKey(ignore: true) + PBContext currentContext; + + InjectedContainer({ + this.bottomRightCorner, + this.topLeftCorner, String name, - String UUID, { + this.UUID, + double alignX, + double alignY, String color, - PBContext currentContext, - PBIntermediateConstraints constraints, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID, constraints: constraints) { + this.currentContext, + this.prototypeNode, + this.size, + this.type, + }) : super( + topLeftCorner, + bottomRightCorner, + currentContext, + name, + UUID: UUID, + ) { generator = PBContainerGenerator(); size = { @@ -42,4 +78,10 @@ class InjectedContainer extends PBVisualIntermediateNode }; } + static PBIntermediateNode fromJson(Map json) => + _$InjectedContainerFromJson(json); + + @override + PBIntermediateNode createIntermediateNode(Map json) => + InjectedContainer.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/injected_container.g.dart b/lib/interpret_and_optimize/entities/injected_container.g.dart new file mode 100644 index 00000000..7e023630 --- /dev/null +++ b/lib/interpret_and_optimize/entities/injected_container.g.dart @@ -0,0 +1,50 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'injected_container.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +InjectedContainer _$InjectedContainerFromJson(Map json) { + return InjectedContainer( + bottomRightCorner: Point.bottomRightFromJson( + json['bottomRightCorner'] as Map), + topLeftCorner: + Point.topLeftFromJson(json['topLeftCorner'] as Map), + name: json['name'] as String, + UUID: json['UUID'] as String, + prototypeNode: + PrototypeNode.prototypeNodeFromJson(json['prototypeNode'] as String), + size: PBIntermediateNode.sizeFromJson(json['size'] as Map), + type: json['type'] as String, + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map); +} + +Map _$InjectedContainerToJson(InjectedContainer instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children, + 'child': instance.child, + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNode': instance.prototypeNode, + 'topLeftCorner': instance.topLeftCorner, + 'bottomRightCorner': instance.bottomRightCorner, + 'type': instance.type, + 'UUID': instance.UUID, + 'size': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart b/lib/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart index 23327ba8..823e5251 100644 --- a/lib/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart +++ b/lib/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart @@ -1,14 +1,10 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; /// Interface that defines that the node was derived from the design files. abstract class PBInheritedIntermediate implements PrototypeEnable { - final originalRef; + final Map originalRef; + PBInheritedIntermediate(this.originalRef); - PBInheritedIntermediate(this.originalRef) { - if (originalRef is DesignNode) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - } + static Map originalRefFromJson(Map json) => + json; } diff --git a/lib/interpret_and_optimize/entities/intermediate_border_info.dart b/lib/interpret_and_optimize/entities/intermediate_border_info.dart new file mode 100644 index 00000000..91b36acf --- /dev/null +++ b/lib/interpret_and_optimize/entities/intermediate_border_info.dart @@ -0,0 +1,34 @@ +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'intermediate_border_info.g.dart'; + +@JsonSerializable() +class IntermediateBorderInfo { + num borderRadius; + + PBColor color; + + num thickness; + + String shape; + + /// Whether `color`, `thickness` and `shape` are available. + /// + /// Note that `borderRadius` should always be enabled + @JsonKey(name: 'isEnabled') + bool isBorderOutlineVisible; + + IntermediateBorderInfo({ + this.borderRadius, + this.color, + this.thickness, + this.shape, + this.isBorderOutlineVisible, + }); + + factory IntermediateBorderInfo.fromJson(Map json) => + _$IntermediateBorderInfoFromJson(json); + + Map toJson() => _$IntermediateBorderInfoToJson(this); +} diff --git a/lib/interpret_and_optimize/entities/intermediate_border_info.g.dart b/lib/interpret_and_optimize/entities/intermediate_border_info.g.dart new file mode 100644 index 00000000..73d8fe2f --- /dev/null +++ b/lib/interpret_and_optimize/entities/intermediate_border_info.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'intermediate_border_info.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +IntermediateBorderInfo _$IntermediateBorderInfoFromJson( + Map json) { + return IntermediateBorderInfo( + borderRadius: json['borderRadius'] as num, + color: json['color'] == null + ? null + : PBColor.fromJson(json['color'] as Map), + thickness: json['thickness'] as num, + shape: json['shape'] as String, + isBorderOutlineVisible: json['isEnabled'] as bool, + ); +} + +Map _$IntermediateBorderInfoToJson( + IntermediateBorderInfo instance) => + { + 'borderRadius': instance.borderRadius, + 'color': instance.color, + 'thickness': instance.thickness, + 'shape': instance.shape, + 'isEnabled': instance.isBorderOutlineVisible, + }; diff --git a/lib/interpret_and_optimize/entities/layouts/column.dart b/lib/interpret_and_optimize/entities/layouts/column.dart index d5653cb9..a3e77561 100644 --- a/lib/interpret_and_optimize/entities/layouts/column.dart +++ b/lib/interpret_and_optimize/entities/layouts/column.dart @@ -100,4 +100,7 @@ class ColumnAlignment extends AlignStrategy{ node.replaceChildren(childrenCopy?.cast()); } } + + @override + PBIntermediateNode fromJson(Map json) => null; } diff --git a/lib/interpret_and_optimize/entities/layouts/row.dart b/lib/interpret_and_optimize/entities/layouts/row.dart index af00909a..7d7c4ba6 100644 --- a/lib/interpret_and_optimize/entities/layouts/row.dart +++ b/lib/interpret_and_optimize/entities/layouts/row.dart @@ -97,4 +97,21 @@ class RowAlignment extends AlignStrategy{ } } + @override + PBLayoutIntermediateNode generateLayout(List children, + PBContext currentContext, String name) { + var row = PBIntermediateRowLayout(name, Uuid().v4(), + currentContext: currentContext); + row.prototypeNode = prototypeNode; + children.forEach((child) => row.addChild(child)); + return row; + } + + @override + void sortChildren() => replaceChildren(children + ..sort((child0, child1) => + child0.topLeftCorner.x.compareTo(child1.topLeftCorner.x))); + + @override + PBIntermediateNode fromJson(Map json) => null; } diff --git a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart index f95d8782..aee83d1c 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart @@ -1,6 +1,6 @@ -import 'package:parabeac_core/design_logic/text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/flexible.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/spacer.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -61,7 +61,7 @@ List handleFlex(bool isVertical, Point topLeft, if (child is! PBIntermediateRowLayout && child is! PBIntermediateColumnLayout) { // Wrap text in container - if (child is! Text) { + if (child is! InheritedText) { resultingChildren.add(_putChildInFlex(isVertical, child, parentLength)); } } else { diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 0b990f38..c9e16976 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -57,4 +57,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { children.forEach((child) => stack.addChild(child)); return stack; } + + @override + PBIntermediateNode fromJson(Map json) => null; } diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index ae6fd2ef..2a56ef44 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -1,4 +1,3 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; @@ -6,25 +5,59 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:json_annotation/json_annotation.dart'; + +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; + +part 'temp_group_layout_node.g.dart'; + +@JsonSerializable(ignoreUnannotated: true, explicitToJson: true) /// A temporary node that must be removed class TempGroupLayoutNode extends PBLayoutIntermediateNode - implements PBInheritedIntermediate { - @override - final originalRef; + implements PBInheritedIntermediate, IntermediateNodeFactory { @override + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; - TempGroupLayoutNode(this.originalRef, PBContext currentContext, String name, - {topLeftCorner, bottomRightCorner, PBIntermediateConstraints constraints}) - : super([], [], currentContext, name, constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - this.topLeftCorner = topLeftCorner; - this.bottomRightCorner = bottomRightCorner; - } + @override + @JsonKey() + String type = 'group'; + + @override + @JsonKey(name: 'UUID') + String UUID; + + @override + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + + @override + PBContext currentContext; + + @override + Map originalRef; + + TempGroupLayoutNode({ + this.originalRef, + this.currentContext, + String name, + this.topLeftCorner, + this.bottomRightCorner, + this.UUID, + this.prototypeNode, + this.size, + }) : super([], [], currentContext, name); @override void addChild(node) { @@ -44,4 +77,20 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode assert(false, 'Attempted to generateLayout for class type [$runtimeType]'); return null; } + + static PBIntermediateNode fromJson(Map json) { + var tempGroup = _$TempGroupLayoutNodeFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + tempGroup.mapRawChildren(json); + + return tempGroup; + } + + @override + PBIntermediateNode createIntermediateNode(Map json) => + (TempGroupLayoutNode.fromJson(json) as TempGroupLayoutNode) + ..originalRef = json; } diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart new file mode 100644 index 00000000..798498d9 --- /dev/null +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart @@ -0,0 +1,40 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'temp_group_layout_node.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { + return TempGroupLayoutNode( + name: json['name'] as String, + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$TempGroupLayoutNodeToJson( + TempGroupLayoutNode instance) => + { + 'subsemantic': instance.subsemantic, + 'child': instance.child?.toJson(), + 'style': instance.auxiliaryData?.toJson(), + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode?.toJson(), + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; diff --git a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart index 654aa052..a675b9a1 100644 --- a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart +++ b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart @@ -2,17 +2,21 @@ import 'dart:math'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:json_annotation/json_annotation.dart'; +@JsonSerializable() /// A node that should not be converted to intermediate. class PBDenyListNode extends PBIntermediateNode { - @override + @override ChildrenStrategy childrenStrategy = NoChildStrategy(); - - PBDenyListNode(Point topLeftCorner, Point bottomRightCorner, - PBContext currentContext, String name, - {String UUID}) - : super( + PBDenyListNode( + Point topLeftCorner, + Point bottomRightCorner, + String name, { + String UUID, + PBContext currentContext, + }) : super( topLeftCorner, bottomRightCorner, UUID, @@ -20,4 +24,6 @@ class PBDenyListNode extends PBIntermediateNode { currentContext: currentContext, ); + @override + PBIntermediateNode fromJson(Map json) => null; } diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index de775ac4..e97e091a 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -1,7 +1,5 @@ import 'dart:math'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_instancesym_gen.dart'; -import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; @@ -12,17 +10,27 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; +import 'alignments/injected_align.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; + +part 'pb_shared_instance.g.dart'; + +@JsonSerializable(ignoreUnannotated: true, explicitToJson: true) /// As some nodes are shared throughout the project, shared instances are pointers to shared master nodes with overridable properties. /// Superclass: PBSharedIntermediateNode - class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode - implements PBInheritedIntermediate { + implements PBInheritedIntermediate, IntermediateNodeFactory { + @JsonKey(name: 'symbolID') final String SYMBOL_ID; ///The parameters that are going to be overriden in the [PBSharedMasterNode]. + @JsonKey(name: 'overrideValues') List sharedParamValues; ///The name of the function call that the [PBSharedInstanceIntermediateNode] is @@ -30,14 +38,34 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode String functionCallName; bool foundMaster = false; - bool isMasterState = false; @override - var originalRef; + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') + PrototypeNode prototypeNode; @override - PrototypeNode prototypeNode; + @JsonKey() + String type = 'shared_instance'; + + @override + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + + @override + String UUID; + + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + + @override + @JsonKey(ignore: true) + PBContext currentContext; @override ChildrenStrategy childrenStrategy = NoChildStrategy(); @@ -49,61 +77,79 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode // quick lookup based on UUID_type Map overrideValuesMap = {}; - PBSharedInstanceIntermediateNode(this.originalRef, this.SYMBOL_ID, - {this.sharedParamValues, - Point topLeftCorner, - Point bottomRightCorner, - PBContext currentContext, - PBIntermediateConstraints constraints}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - (originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width), - (originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height)), - currentContext, - originalRef.name, - UUID: originalRef.UUID, - constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } + @override + @JsonKey(ignore: true) + Map originalRef; + + PBSharedInstanceIntermediateNode({ + this.originalRef, + this.SYMBOL_ID, + this.sharedParamValues, + this.topLeftCorner, + this.bottomRightCorner, + this.currentContext, + this.UUID, + this.prototypeNode, + this.size, + this.overrideValues, + String name, + }) : super(topLeftCorner, bottomRightCorner, currentContext, name, + UUID: UUID) { generator = PBSymbolInstanceGenerator(); - overrideValues = sharedParamValues.map((v) { - var symOvrValue = - PBSymbolInstanceOverridableValue(v.UUID, v.value, v.type); - overrideValuesMap[v.overrideName] = symOvrValue; - return symOvrValue; - }).toList() - ..removeWhere((v) => v == null || v.value == null); + /// if [sharedParamValues] sets [overrideValues], then only pass one + // overrideValues = sharedParamValues.map((v) { + // var symOvrValue = + // PBSymbolInstanceOverridableValue(v.UUID, v.value, v.type); + // overrideValuesMap[v.overrideName] = symOvrValue; + // return symOvrValue; + // }).toList() + // ..removeWhere((v) => v == null || v.value == null); } + static PBIntermediateNode fromJson(Map json) => + _$PBSharedInstanceIntermediateNodeFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json; + + @override + PBIntermediateNode createIntermediateNode(Map json) => + PBSharedInstanceIntermediateNode.fromJson(json); } +@JsonSerializable() class PBSharedParameterValue { - final Type _type; - Type get type => _type; - set type(Type type) => _type; + final String type; - final dynamic _value; - dynamic get value => _value; + /// Initial value of [PBSharedParameterValue] + @JsonKey(name: 'value') + dynamic initialValue; - final String _UUID; - String get UUID => _UUID; + /// Current value of [PBSharedParameterValue] + /// + /// This is useful when we need to do something to `initialValue` + /// in order to correctly export the Override + @JsonKey(ignore: true) + String value; - final String _overrideName; - String get overrideName => _overrideName; + final String UUID; - String get name => - SN_UUIDtoVarName[PBInputFormatter.findLastOf(_overrideName, '/')]; + @JsonKey(name: 'name') + String overrideName; PBSharedParameterValue( - this._type, - this._value, - this._UUID, - this._overrideName, - ); + this.type, + this.initialValue, + this.UUID, + this.overrideName, + ) { + value = initialValue; + } + + @override + factory PBSharedParameterValue.fromJson(Map json) => + _$PBSharedParameterValueFromJson(json); + + Map toJson() => _$PBSharedParameterValueToJson(this); } diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart new file mode 100644 index 00000000..0ac0c838 --- /dev/null +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart @@ -0,0 +1,75 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'pb_shared_instance.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( + Map json) { + return PBSharedInstanceIntermediateNode( + SYMBOL_ID: json['symbolID'] as String, + sharedParamValues: (json['overrideValues'] as List) + ?.map((e) => e == null + ? null + : PBSharedParameterValue.fromJson(e as Map)) + ?.toList(), + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + name: json['name'] as String, + ) + ..subsemantic = json['subsemantic'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList() + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$PBSharedInstanceIntermediateNodeToJson( + PBSharedInstanceIntermediateNode instance) => + { + 'subsemantic': instance.subsemantic, + 'children': instance.children?.map((e) => e?.toJson())?.toList(), + 'child': instance.child?.toJson(), + 'style': instance.auxiliaryData?.toJson(), + 'name': instance.name, + 'symbolID': instance.SYMBOL_ID, + 'overrideValues': + instance.sharedParamValues?.map((e) => e?.toJson())?.toList(), + 'prototypeNodeUUID': instance.prototypeNode?.toJson(), + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + }; + +PBSharedParameterValue _$PBSharedParameterValueFromJson( + Map json) { + return PBSharedParameterValue( + json['type'] as String, + json['value'], + json['UUID'] as String, + json['name'] as String, + ); +} + +Map _$PBSharedParameterValueToJson( + PBSharedParameterValue instance) => + { + 'type': instance.type, + 'value': instance.initialValue, + 'UUID': instance.UUID, + 'name': instance.overrideName, + }; diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index a7002603..a3177f1a 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -1,70 +1,113 @@ import 'dart:math'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_mastersym_gen.dart'; -import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/override_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; import 'package:quick_log/quick_log.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; +import 'package:recase/recase.dart'; -class PBSharedMasterNode extends PBVisualIntermediateNode - implements PBInheritedIntermediate { +part 'pb_shared_master_node.g.dart'; - @override - final originalRef; +@JsonSerializable(ignoreUnannotated: true, explicitToJson: true) +class PBSharedMasterNode extends PBVisualIntermediateNode + implements PBInheritedIntermediate, IntermediateNodeFactory { @override + @JsonKey( + fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; ///The unique symbol identifier of the [PBSharedMasterNode] + @JsonKey(name: 'symbolID') final String SYMBOL_ID; + @override + @JsonKey() + String type = 'shared_master'; + + @override + @JsonKey(ignore: true) + Point topLeftCorner; + @override + @JsonKey(ignore: true) + Point bottomRightCorner; + + @override + String UUID; + + @override + @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') + Map size; + + @override + @JsonKey(ignore: true) + PBContext currentContext; + List parametersDefinition; Map parametersDefsMap = {}; ///The children that makes the UI of the [PBSharedMasterNode]. The children are going to be wrapped ///using a [TempGroupLayoutNode] as the root Node. set children(List children) { - child ??= TempGroupLayoutNode(originalRef, currentContext, name); + child ??= TempGroupLayoutNode(currentContext: currentContext, name: name); if (child is PBLayoutIntermediateNode) { children.forEach((element) => child.addChild(element)); } else { - child = TempGroupLayoutNode(originalRef, currentContext, name) + child = TempGroupLayoutNode(currentContext: currentContext, name: name) ..replaceChildren([child, ...children]); } } ///The properties that could be be overridable on a [PBSharedMasterNode] - + @JsonKey(name: 'overrideProperties') List overridableProperties; String friendlyName; - PBSharedMasterNode( + @override + @JsonKey(ignore: true) + Map originalRef; + + PBSharedMasterNode({ this.originalRef, this.SYMBOL_ID, String name, - Point topLeftCorner, - Point bottomRightCorner, { + this.topLeftCorner, + this.bottomRightCorner, this.overridableProperties, - PBContext currentContext, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: originalRef.UUID ?? '') { + this.currentContext, + this.UUID, + this.prototypeNode, + this.size, + }) : super( + topLeftCorner, + bottomRightCorner, + currentContext, + name, + UUID: UUID ?? '', + ) { + overridableProperties ??= []; try { - //Remove any special characters and leading numbers from the method name - friendlyName = name - .replaceAll(RegExp(r'[^\w]+'), '') - .replaceAll(RegExp(r'/'), '') - .replaceFirst(RegExp(r'^[\d]+'), ''); - //Make first letter of method name capitalized - friendlyName = friendlyName[0].toUpperCase() + friendlyName.substring(1); + if (name != null) { + //Remove any special characters and leading numbers from the method name + friendlyName = name + .replaceAll(RegExp(r'[^\w]+'), '') + .replaceAll(RegExp(r'/'), '') + .replaceFirst(RegExp(r'^[\d]+'), ''); + //Make first letter of method name capitalized + friendlyName = + friendlyName[0].toUpperCase() + friendlyName.substring(1); + } } catch (e, stackTrace) { MainInfo().sentry.captureException( exception: e, @@ -73,67 +116,77 @@ class PBSharedMasterNode extends PBVisualIntermediateNode logger.error(e.toString()); } - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } generator = PBMasterSymbolGenerator(); - this.currentContext.screenBottomRightCorner = Point( - originalRef.boundaryRectangle.x + originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + originalRef.boundaryRectangle.height); - this.currentContext.screenTopLeftCorner = - Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y); - - parametersDefinition = overridableProperties.map((p) { - var PBSymMasterP = PBSymbolMasterParameter( - p._friendlyName, - p.type, - p.UUID, - p.canOverride, - p.propertyName, - /* Removed Parameter Definition as it was accepting JSON?*/ - null, // TODO: @Eddie - currentContext.screenTopLeftCorner.x, - currentContext.screenTopLeftCorner.y, - currentContext.screenBottomRightCorner.x, - currentContext.screenBottomRightCorner.y, - context: currentContext); - parametersDefsMap[p.propertyName] = PBSymMasterP; - return PBSymMasterP; - }).toList() - ..removeWhere((p) => p == null || p.parameterDefinition == null); + overridableProperties.forEach(OverrideHelper.addProperty); + + // this.currentContext.screenBottomRightCorner = Point( + // originalRef.boundaryRectangle.x + originalRef.boundaryRectangle.width, + // originalRef.boundaryRectangle.y + originalRef.boundaryRectangle.height); + // this.currentContext.screenTopLeftCorner = + // Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y); + + // parametersDefinition = overridableProperties.map((p) { + // var PBSymMasterP = PBSymbolMasterParameter( + // // p._friendlyName, + // p.type, + // p.value, + // p.UUID, + // p.canOverride, + // p.propertyName, + // /* Removed Parameter Definition as it was accepting JSON?*/ + // null, // TODO: @Eddie + // currentContext.screenTopLeftCorner.x, + // currentContext.screenTopLeftCorner.y, + // currentContext.screenBottomRightCorner.x, + // currentContext.screenBottomRightCorner.y, + // context: currentContext); + // parametersDefsMap[p.propertyName] = PBSymMasterP; + // return PBSymMasterP; + // }).toList() + // ..removeWhere((p) => p == null || p.parameterDefinition == null); } @override void addChild(node) => child == null ? child = node : children = [node]; + + + static PBIntermediateNode fromJson(Map json) => + _$PBSharedMasterNodeFromJson(json) + ..topLeftCorner = Point.topLeftFromJson(json) + ..bottomRightCorner = Point.bottomRightFromJson(json) + ..originalRef = json + ..mapRawChildren(json); + + @override + PBIntermediateNode createIntermediateNode(Map json) => + PBSharedMasterNode.fromJson(json); } +@JsonSerializable() class PBSharedParameterProp { - final Type _type; - Type get type => _type; - set type(Type type) => _type; + final String type; PBIntermediateNode value; - final bool _canOverride; - bool get canOverride => _canOverride; + @JsonKey(name: 'name', fromJson: _propertyNameFromJson) + final String propertyName; - final String _propertyName; - String get propertyName => _propertyName; + final String UUID; - final String _UUID; - String get UUID => _UUID; + PBSharedParameterProp( + this.type, + this.value, + this.propertyName, + this.UUID, + ); - final dynamic _initialValue; - dynamic get initialValue => _initialValue; + factory PBSharedParameterProp.fromJson(Map json) => + _$PBSharedParameterPropFromJson(json); - final String _friendlyName; - String get friendlyName => - _friendlyName ?? - SN_UUIDtoVarName[PBInputFormatter.findLastOf(propertyName, '/')] ?? - 'noname'; + Map toJson() => _$PBSharedParameterPropToJson(this); - PBSharedParameterProp(this._friendlyName, this._type, this.value, - this._canOverride, this._propertyName, this._UUID, this._initialValue); + static String _propertyNameFromJson(String name) => + name.replaceAll(RegExp(r'[^A-Za-z0-9]'), '').camelCase; } diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart new file mode 100644 index 00000000..ac36705d --- /dev/null +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart @@ -0,0 +1,69 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'pb_shared_master_node.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { + return PBSharedMasterNode( + SYMBOL_ID: json['symbolID'] as String, + name: json['name'] as String, + overridableProperties: (json['overrideProperties'] as List) + ?.map((e) => e == null + ? null + : PBSharedParameterProp.fromJson(e as Map)) + ?.toList(), + UUID: json['UUID'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + size: PBIntermediateNode.sizeFromJson( + json['boundaryRectangle'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..child = json['child'] == null + ? null + : PBIntermediateNode.fromJson(json['child'] as Map) + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$PBSharedMasterNodeToJson(PBSharedMasterNode instance) => + { + 'subsemantic': instance.subsemantic, + 'child': instance.child?.toJson(), + 'style': instance.auxiliaryData?.toJson(), + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode?.toJson(), + 'symbolID': instance.SYMBOL_ID, + 'type': instance.type, + 'UUID': instance.UUID, + 'boundaryRectangle': instance.size, + 'overrideProperties': + instance.overridableProperties?.map((e) => e?.toJson())?.toList(), + }; + +PBSharedParameterProp _$PBSharedParameterPropFromJson( + Map json) { + return PBSharedParameterProp( + json['type'] as String, + json['value'] == null + ? null + : PBIntermediateNode.fromJson(json['value'] as Map), + PBSharedParameterProp._propertyNameFromJson(json['name'] as String), + json['UUID'] as String, + ); +} + +Map _$PBSharedParameterPropToJson( + PBSharedParameterProp instance) => + { + 'type': instance.type, + 'value': instance.value, + 'name': instance.propertyName, + 'UUID': instance.UUID, + }; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 5251f216..61c3d3c3 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attr import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; @@ -15,14 +16,24 @@ import 'package:quick_log/quick_log.dart'; /// PB’s representation of the intermediate representation for a sketch node. /// Usually, we work with its subclasses. We normalize several aspects of data that a sketch node presents in order to work better at the intermediate level. /// Sometimes, PBNode’s do not have a direct representation of a sketch node. For example, most layout nodes are primarily made through and understanding of a need for a layout. +import 'package:json_annotation/json_annotation.dart'; + +part 'pb_intermediate_node.g.dart'; + +@JsonSerializable( + explicitToJson: true, + createFactory: false, +) abstract class PBIntermediateNode extends TraversableNode { Logger logger; /// A subsemantic is contextual info to be analyzed in or in-between the visual generation & layout generation services. String subsemantic; + @JsonKey(ignore: true) PBGenerator generator; + @JsonKey() final String UUID; PBIntermediateConstraints constraints; @@ -33,6 +44,7 @@ abstract class PBIntermediateNode extends TraversableNode { /// that attribute. List _attributes; + @JsonKey(ignore: true) List get attributes => _attributes; @override @@ -58,19 +70,25 @@ abstract class PBIntermediateNode extends TraversableNode { } } + @JsonKey(fromJson: Point.topLeftFromJson) Point topLeftCorner; + + @JsonKey(fromJson: Point.bottomRightFromJson) Point bottomRightCorner; double get width => (bottomRightCorner.x - topLeftCorner.x).toDouble(); double get height => (bottomRightCorner.y - topLeftCorner.y).toDouble(); + @JsonKey(ignore: true) PBContext currentContext; + @JsonKey(ignore: true) PBGenerationViewData get managerData => currentContext.tree.data; Map size; /// Auxillary Data of the node. Contains properties such as BorderInfo, Alignment, Color & a directed graph of states relating to this element. + @JsonKey(name: 'style') IntermediateAuxiliaryData auxiliaryData = IntermediateAuxiliaryData(); /// Name of the element if available. @@ -169,6 +187,27 @@ abstract class PBIntermediateNode extends TraversableNode { child?.align(context.clone()); } } + + factory PBIntermediateNode.fromJson(Map json) => + AbstractIntermediateNodeFactory.getIntermediateNode(json); + + Map toJson() => _$PBIntermediateNodeToJson(this); + + static Map sizeFromJson(Map json) { + return { + 'width': json['width'], + 'height': json['height'], + }; + } + + void mapRawChildren(Map json) { + var rawChildren = json['children'] as List; + rawChildren?.forEach((child) { + if (child != null) { + addChild(PBIntermediateNode.fromJson(child)); + } + }); + } } extension PBPointLegacyMethod on Point { @@ -193,5 +232,7 @@ extension PBPointLegacyMethod on Point { return y == point.y ? x >= point.x : y >= point.y; } return false; - } + + } +} \ No newline at end of file diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart new file mode 100644 index 00000000..ff96c83c --- /dev/null +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart @@ -0,0 +1,20 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'pb_intermediate_node.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Map _$PBIntermediateNodeToJson(PBIntermediateNode instance) => + { + 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, + 'children': instance.children?.map((e) => e?.toJson())?.toList(), + 'child': instance.child?.toJson(), + 'topLeftCorner': instance.topLeftCorner?.toJson(), + 'bottomRightCorner': instance.bottomRightCorner?.toJson(), + 'size': instance.size, + 'style': instance.auxiliaryData?.toJson(), + 'name': instance.name, + }; diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart new file mode 100644 index 00000000..99d73f1d --- /dev/null +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -0,0 +1,88 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_circle.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_oval.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_polygon.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_path.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_star.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_triangle.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; + +class AbstractIntermediateNodeFactory { + static final String INTERMEDIATE_TYPE = 'type'; + + static final Set _intermediateNodes = { + InheritedBitmap(), + InheritedCircle(), + InheritedContainer(), + InheritedOval(), + InheritedPolygon(), + InheritedScaffold(), + InheritedShapeGroup(), + InheritedShapePath(), + InheritedStar(), + InheritedText(), + InheritedTriangle(), + PBSharedInstanceIntermediateNode(), + PBSharedMasterNode(), + TempGroupLayoutNode(), + PBIntermediateTree(), + }; + + AbstractIntermediateNodeFactory(); + + static dynamic getIntermediateNode(Map json) { + var className = json[INTERMEDIATE_TYPE]; + if (className != null) { + for (var candidate in _intermediateNodes) { + if (candidate.type == className) { + var iNode = candidate.createIntermediateNode(json); + + // Check if `iNode` is a tag + var tag = PBPluginListHelper().returnAllowListNodeIfExists(iNode); + // Return tag if it exists + if (tag != null) { + return tag; + } + return iNode; + } + } + } + return null; + } + + /// Checks whether `node` is a state management node, and interprets it accordingly. + /// + /// Returns `null` if `node` is a non-default state management node, effectively removing `node` from the tree. + /// Returns `node` if it is a default state management node or a non-state management node. + static PBIntermediateNode interpretStateManagement(PBIntermediateNode node) { + if (node is! PBSharedMasterNode) { + return node; + } + var smHelper = PBStateManagementHelper(); + if (smHelper.isValidStateNode(node.name)) { + if (smHelper.isDefaultNode(node)) { + smHelper.interpretStateManagementNode(node); + return node; + } else { + smHelper.interpretStateManagementNode(node); + return null; + } + } + return node; + } +} + +abstract class IntermediateNodeFactory { + String type; + dynamic createIntermediateNode(Map json); +} diff --git a/lib/interpret_and_optimize/helpers/index_walker.dart b/lib/interpret_and_optimize/helpers/index_walker.dart new file mode 100644 index 00000000..b7cedaa0 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/index_walker.dart @@ -0,0 +1,12 @@ +/// Class that helps traversing a [Map] without running into null errors +class IndexWalker { + dynamic value; + IndexWalker(this.value); + + IndexWalker operator [](Object index) { + if (value != null) { + value = value[index]; + } + return this; + } +} diff --git a/lib/interpret_and_optimize/helpers/node_tuple.dart b/lib/interpret_and_optimize/helpers/node_tuple.dart index b52563aa..8ed652ff 100644 --- a/lib/interpret_and_optimize/helpers/node_tuple.dart +++ b/lib/interpret_and_optimize/helpers/node_tuple.dart @@ -1,14 +1,14 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +// import 'package:parabeac_core/design_logic/design_node.dart'; +// import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -/// A simple child Sketch Node & Converted Parent Node holder. (Tuple) -class NodeTuple { - /// Child Sketch Node - DesignNode designNode; +// /// A simple child Sketch Node & Converted Parent Node holder. (Tuple) +// class NodeTuple { +// /// Child Sketch Node +// DesignNode designNode; - /// Parent Intermediate node where `sketchNode.interpretNode()` should be assigned as a child. - PBIntermediateNode convertedParent; +// /// Parent Intermediate node where `sketchNode.interpretNode()` should be assigned as a child. +// PBIntermediateNode convertedParent; - /// Constructor for NodeTuple. - NodeTuple(this.designNode, this.convertedParent); -} +// /// Constructor for NodeTuple. +// NodeTuple(this.designNode, this.convertedParent); +// } diff --git a/lib/interpret_and_optimize/helpers/override_helper.dart b/lib/interpret_and_optimize/helpers/override_helper.dart new file mode 100644 index 00000000..c940337b --- /dev/null +++ b/lib/interpret_and_optimize/helpers/override_helper.dart @@ -0,0 +1,30 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; + +class OverrideHelper { + /// Map to keep track of overrides. + /// + /// The `key` is the [UUID] of the override property, + /// while the `value` is the [List] of the properties for that particular element. + /// This is useful in the case that a single UUID contains many overrides like text content and text style. + static final SN_UUIDtoVarName = >{}; + + /// Adds `property` to `SN_UUIDtoVarName` map based on `property`'s [UUID] + static void addProperty(PBSharedParameterProp property) { + if (SN_UUIDtoVarName.containsKey(property.UUID)) { + SN_UUIDtoVarName[property.UUID].add(property); + } else { + SN_UUIDtoVarName[property.UUID] = [property]; + } + } + + /// Returns a `PBSharedParameterProp` matching given `uuid` and `type` of override. + /// + /// Returns [null] if no match is found + static PBSharedParameterProp getProperty(String uuid, String type) { + if (SN_UUIDtoVarName.containsKey(uuid)) { + return SN_UUIDtoVarName[uuid] + .firstWhere((element) => element.type == type, orElse: () => null); + } + return null; + } +} \ No newline at end of file diff --git a/lib/interpret_and_optimize/helpers/pb_color.dart b/lib/interpret_and_optimize/helpers/pb_color.dart new file mode 100644 index 00000000..55a88b02 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/pb_color.dart @@ -0,0 +1,72 @@ +import 'package:hex/hex.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/index_walker.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'pb_color.g.dart'; + +@JsonSerializable() +class PBColor { + num alpha; + num red; + num green; + num blue; + + PBColor( + this.alpha, + this.red, + this.green, + this.blue, + ); + + factory PBColor.fromJson(Map json) => + _$PBColorFromJson(json); + + Map toJson() => _$PBColorToJson(this); + + @override + String toString() => ColorUtils.toHex(this); +} + +class ColorUtils { + static String toHex(PBColor color) { + if (color != null) { + int a, r, g, b; + a = ((color.alpha ?? 0) * 255).round(); + r = ((color.red ?? 0) * 255).round(); + g = ((color.green ?? 0) * 255).round(); + b = ((color.blue ?? 0) * 255).round(); + return '0x' + HEX.encode([a, r, g, b]); + } else { + return '0x' + HEX.encode([0, 0, 0, 0]); + } + } + + static String findDefaultColor(String hex) { + switch (hex) { + case '0xffffffff': + return 'Colors.white'; + break; + case '0xff000000': + return 'Colors.black'; + break; + } + return null; + } + + /// Returns a json representation of color assuming we receive a PBSL `style` in json format + static PBColor pbColorFromJsonFills(List> json) { + var fills = IndexWalker(json).value; + + if (fills != null && fills.isNotEmpty) { + // Get first fill that has a color and is enabled + var fill = fills.firstWhere( + (fill) => fill['isEnabled'] as bool && fill['color'] != null, + orElse: () => null); + + if (fill != null) { + return PBColor.fromJson(fill['color']); + } + } + return null; + } +} diff --git a/lib/interpret_and_optimize/helpers/pb_color.g.dart b/lib/interpret_and_optimize/helpers/pb_color.g.dart new file mode 100644 index 00000000..752da148 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/pb_color.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'pb_color.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PBColor _$PBColorFromJson(Map json) { + return PBColor( + json['alpha'] as num, + json['red'] as num, + json['green'] as num, + json['blue'] as num, + ); +} + +Map _$PBColorToJson(PBColor instance) => { + 'alpha': instance.alpha, + 'red': instance.red, + 'green': instance.green, + 'blue': instance.blue, + }; diff --git a/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart index f6e88e10..4789d44f 100644 --- a/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart @@ -1,7 +1,8 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_deny_list_node.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; + // Helping understand indirect and direct semantics that should remove a node from a tree. class PBDenyListHelper { Map denyList = { @@ -13,16 +14,16 @@ class PBDenyListHelper { '937FDFA9-BCF9-4577-AE5E-0CF7FDD47254': true, }; - bool isInDenyListDirect(DesignNode node) { + bool isInDenyListDirect(PBIntermediateNode node) { if (denyList[node.UUID] != null) { return true; } return false; } - PBDenyListNode returnDenyListNodeIfExist(DesignNode node) { + PBDenyListNode returnDenyListNodeIfExist(PBIntermediateNode node) { if (isInDenyListDirect(node)) { - return PBDenyListNode(Point(0, 0), Point(0, 0), null, ''); + return PBDenyListNode(Point(0, 0), Point(0, 0), ''); } else { return null; } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 371a880f..7819bce0 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -2,11 +2,15 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_view_data import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; import 'package:recase/recase.dart'; import 'package:tuple/tuple.dart'; import "dart:collection"; import 'package:uuid/uuid.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'pb_intermediate_node_tree.g.dart'; enum TREE_TYPE { MISC, @@ -14,13 +18,19 @@ enum TREE_TYPE { VIEW, } -class PBIntermediateTree extends Iterable { +@JsonSerializable() +class PBIntermediateTree extends Iterable + implements IntermediateNodeFactory { String _UUID; String get UUID => _UUID; /// The [TREE_TYPE] of the [PBIntermediateTree]. - TREE_TYPE _tree_type = TREE_TYPE.SCREEN; - TREE_TYPE get tree_type => _tree_type; + @JsonKey(ignore: true) + TREE_TYPE tree_type = TREE_TYPE.SCREEN; + + @override + @JsonKey(ignore: true) + String type = 'tree'; /// This flag makes the data in the [PBIntermediateTree] unmodifiable. Therefore, /// if a change is made and [lockData] is `true`, the change is going to be ignored. @@ -29,9 +39,11 @@ class PBIntermediateTree extends Iterable { /// Furthermore, this is a workaround to the unability of creating a copy of the [PBIntermediateTree] to prevent /// the modifications to the object (https://github.com/dart-lang/sdk/issues/3367). As a result, the [lockData] flag /// has to be used to prevent those modification in phases where the data needs to be analyzed but unmodified. + @JsonKey(ignore: true) bool lockData = false; PBGenerationViewData _data; + @JsonKey(ignore: true) PBGenerationViewData get data => _data; set data(PBGenerationViewData viewData) { if (!lockData) { @@ -40,6 +52,7 @@ class PBIntermediateTree extends Iterable { } PBIntermediateNode _rootNode; + @JsonKey(name: 'designNode') PBIntermediateNode get rootNode => _rootNode; set rootNode(PBIntermediateNode rootNode) { if (!lockData) { @@ -47,11 +60,11 @@ class PBIntermediateTree extends Iterable { _identifier ??= rootNode?.name?.snakeCase ?? name.snakeCase; if (rootNode is InheritedScaffold) { - _tree_type = TREE_TYPE.SCREEN; + tree_type = TREE_TYPE.SCREEN; } else if (rootNode is PBSharedMasterNode) { - _tree_type = TREE_TYPE.VIEW; + tree_type = TREE_TYPE.VIEW; } else { - _tree_type = TREE_TYPE.MISC; + tree_type = TREE_TYPE.MISC; } } } @@ -78,9 +91,13 @@ class PBIntermediateTree extends Iterable { /// platform or orientation. The [identifier] is just going to be set once, its going /// to be the [name] of the [rootNode]. String _identifier; + @JsonKey(name: 'name') String get identifier => _identifier?.snakeCase ?? 'no_name_found'; - PBIntermediateTree(this._name) { + PBIntermediateTree({ + String name, + }) { + _name = name; _dependentsOn = {}; _UUID = Uuid().v4(); } @@ -155,6 +172,16 @@ class PBIntermediateTree extends Iterable { @override Iterator get iterator => IntermediateDFSIterator(this); + + Map toJson() => _$PBIntermediateTreeToJson(this); + + static PBIntermediateTree fromJson(Map json) => + _$PBIntermediateTreeFromJson(json) + ..tree_type = treeTypeFromJson(json['designNode']); + + @override + PBIntermediateTree createIntermediateNode(Map json) => + PBIntermediateTree.fromJson(json); } /// By extending the class, any node could be used in any iterator to traverse its @@ -168,3 +195,14 @@ abstract class TraversableNode { int treeLevel; List children; } + +TREE_TYPE treeTypeFromJson(Map json) { + switch (json['type']) { + case 'artboard': + return TREE_TYPE.SCREEN; + case 'shared_master': + return TREE_TYPE.VIEW; + default: + return TREE_TYPE.MISC; + } +} diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart new file mode 100644 index 00000000..e07b03ed --- /dev/null +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'pb_intermediate_node_tree.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PBIntermediateTree _$PBIntermediateTreeFromJson(Map json) { + return PBIntermediateTree( + name: json['name'] as String, + )..rootNode = json['designNode'] == null + ? null + : PBIntermediateNode.fromJson(json['designNode'] as Map); +} + +Map _$PBIntermediateTreeToJson(PBIntermediateTree instance) => + { + 'designNode': instance.rootNode, + 'name': instance.name, + }; diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index d8a39334..7aa62ddf 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -1,11 +1,8 @@ -import 'package:parabeac_core/design_logic/artboard.dart'; -import 'package:parabeac_core/design_logic/pb_shared_instance_design_node.dart'; import 'package:parabeac_core/eggs/custom_egg.dart'; import 'package:parabeac_core/eggs/injected_app_bar.dart'; import 'package:parabeac_core/eggs/injected_tab.dart'; import 'package:parabeac_core/eggs/injected_tab_bar.dart'; -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/input/sketch/entities/layers/symbol_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'dart:math'; @@ -28,7 +25,24 @@ class PBPluginListHelper { factory PBPluginListHelper() => _instance; - PBPluginListHelper._internal(); + PBPluginListHelper._internal() { + allowListNames = { + '': InjectedTabBar( + Point(0, 0), + Point(0, 0), + Uuid().v4(), + '', + ), + '': InjectedAppbar( + Point(0, 0), + Point(0, 0), + Uuid().v4(), + '', + ), + '': Tab(Point(0, 0), Point(0, 0), '', UUID: Uuid().v4()), + '': CustomEgg(Point(0, 0), Point(0, 0), ''), + }; + } Map allowListNames; @@ -67,21 +81,16 @@ class PBPluginListHelper { /// Iterates through Plugin List and checks for a match of `node.name`. /// Returns the PluginNode associated if it exists. - PBEgg returnAllowListNodeIfExists(DesignNode node) { - // InjectedContainer(null,null)..subsemantic = ''; - if (node is! PBArtboard && node is! PBSharedInstanceDesignNode) { + PBEgg returnAllowListNodeIfExists(PBIntermediateNode node) { + if (node != null) { for (var key in allowListNames.keys) { - if (node.name.contains(key)) { + if (node.name?.contains(key) ?? false) { return allowListNames[key].generatePluginNode( - Point(node.boundaryRectangle.x, node.boundaryRectangle.y), - Point(node.boundaryRectangle.x + node.boundaryRectangle.width, - node.boundaryRectangle.y + node.boundaryRectangle.height), - node); + node.topLeftCorner, node.bottomRightCorner, node); } } } + return null; } - - returnDenyListNodeIfExist(SymbolInstance symbolInstance) {} } diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index bf652d01..7bdf4c90 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -1,11 +1,18 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; -import 'package:parabeac_core/input/sketch/entities/style/shared_style.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; +import 'package:quick_log/quick_log.dart'; +part 'pb_project.g.dart'; + +@JsonSerializable(explicitToJson: true) class PBProject { + @JsonKey(name: 'name') final String projectName; - final String projectAbsPath; + String projectAbsPath; /// This flag makes the data in the [PBProject] unmodifiable. Therefore, /// if a change is made and [lockData] is `true`, the change is going to be ignored. @@ -18,6 +25,7 @@ class PBProject { /// the modifications to the object (https://github.com/dart-lang/sdk/issues/3367). As a result, the [lockData] flag /// has to be used to prevent those modification in phases where the data needs to be analyzed but unmodified. bool _lockData = false; + @JsonKey(ignore: true) bool get lockData => _lockData; set lockData(lock) { _lockData = lock; @@ -25,14 +33,15 @@ class PBProject { } List _forest; + @JsonKey(fromJson: PBProject.forestFromJson, name: 'pages') List get forest => _forest; + @JsonKey(fromJson: PBProject.forestFromJson, name: 'pages') set forest(List forest) { if (!lockData) { _forest = forest; } } - List sharedStyles = []; @Deprecated( 'Use the fileStructureStrategy within the GenerationConfiguration') FileStructureStrategy _fileStructureStrategy; @@ -40,6 +49,7 @@ class PBProject { set genProjectData(PBGenerationProjectData projectData) => _genProjectData = projectData; + @JsonKey(ignore: true) PBGenerationProjectData get genProjectData => _genProjectData; @Deprecated( @@ -49,13 +59,44 @@ class PBProject { @Deprecated( 'Use the fileStructureStrategy within the GenerationConfiguration') + @JsonKey(ignore: true) FileStructureStrategy get fileStructureStrategy => _fileStructureStrategy; - PBProject(this.projectName, this.projectAbsPath, this.sharedStyles, + @JsonKey(ignore: true) + static Logger log = Logger('PBProject'); + + PBProject(this.projectName, this.projectAbsPath, {FileStructureStrategy fileStructureStrategy}) { _forest = []; _genProjectData = PBGenerationProjectData(); _fileStructureStrategy = fileStructureStrategy; _genProjectData = PBGenerationProjectData(); } + + factory PBProject.fromJson(Map json) => + _$PBProjectFromJson(json); + + Map toJson() => _$PBProjectToJson(this); + + /// Maps JSON pages to a list of [PBIntermediateTree] + static List forestFromJson( + List> pages) { + var trees = []; + pages.forEach((page) { + var screens = (page['screens'] as Iterable).map((screen) { + // Generate Intermedite tree + var tree = PBIntermediateTree.fromJson(screen)..name = page['name']; + tree.data = PBGenerationViewData(); + + if (tree != null) { + PBProject.log.fine( + 'Processed \'${tree.name}\' in page \'${tree.identifier}\' with item type: \'${tree.tree_type}\''); + } + return tree; + }).toList(); + trees.addAll(screens); + }); + + return trees; + } } diff --git a/lib/interpret_and_optimize/helpers/pb_project.g.dart b/lib/interpret_and_optimize/helpers/pb_project.g.dart new file mode 100644 index 00000000..8078e407 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/pb_project.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'pb_project.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PBProject _$PBProjectFromJson(Map json) { + return PBProject( + json['name'] as String, + json['projectAbsPath'] as String, + )..forest = + PBProject.forestFromJson(json['pages'] as List>); +} + +Map _$PBProjectToJson(PBProject instance) => { + 'name': instance.projectName, + 'projectAbsPath': instance.projectAbsPath, + 'pages': instance.forest?.map((e) => e?.toJson())?.toList(), + }; diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 0e50da57..efa57d1d 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -1,5 +1,4 @@ import 'package:parabeac_core/controllers/interpret.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -14,6 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/state_management/intermedia import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_variation.dart'; class PBStateManagementLinker { + Interpret interpret; PBStateManagementLinker._internal() { interpret = Interpret(); _statemap = {}; @@ -25,7 +25,7 @@ class PBStateManagementLinker { factory PBStateManagementLinker() => _instance; - Interpret interpret; + // Interpret interpret; Map _statemap; diff --git a/lib/interpret_and_optimize/helpers/pb_symbol_storage.dart b/lib/interpret_and_optimize/helpers/pb_symbol_storage.dart index 4d9b4948..4426542f 100644 --- a/lib/interpret_and_optimize/helpers/pb_symbol_storage.dart +++ b/lib/interpret_and_optimize/helpers/pb_symbol_storage.dart @@ -71,13 +71,13 @@ class PBSymbolStorage { ///Looks for the symbol in both the [_pbSharedMasterNodes] and ///the [pageSymbols] maps PBIntermediateNode getSymbol(String id) { - var node = getSharedInstaceNode(id); - node ??= getSharedMasterNode(id) as PBIntermediateNode; + PBIntermediateNode node = getSharedInstaceNode(id); + node ??= getSharedMasterNode(id); return node; } /// Removes the symbol with given [id]. - /// + /// /// Returns [true] if the object was successfuly removed, /// [false] if the object did not exist. bool removeSymbolWithId(String id) { @@ -105,7 +105,7 @@ class PBSymbolStorage { String getNameOfSymbolWithID(String id) { return _pbSharedMasterNodes.containsKey(id) - ? _pbSharedMasterNodes[id].originalRef.name + ? _pbSharedMasterNodes[id].name : null; } } diff --git a/lib/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart b/lib/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart new file mode 100644 index 00000000..2e36e3b4 --- /dev/null +++ b/lib/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart @@ -0,0 +1,8 @@ +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:pbdl/pbdl.dart'; + +abstract class DesignToPBDLService { + DesignType designType; + + Future callPBDL(MainInfo info); +} diff --git a/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart b/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart new file mode 100644 index 00000000..58e26434 --- /dev/null +++ b/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart @@ -0,0 +1,16 @@ +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart'; +import 'package:pbdl/pbdl.dart'; +import 'package:path/path.dart' as p; + +class FigmaToPBDLService implements DesignToPBDLService { + @override + DesignType designType = DesignType.FIGMA; + + @override + Future callPBDL(MainInfo info) => PBDL.fromFigma( + info.figmaProjectID, + info.figmaKey, + outputPath: p.join(info.genProjectPath, 'assets'), + ); +} diff --git a/lib/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart b/lib/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart new file mode 100644 index 00000000..dda30f3b --- /dev/null +++ b/lib/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart @@ -0,0 +1,17 @@ +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart'; +import 'package:pbdl/pbdl.dart'; +import 'package:path/path.dart' as p; + +class SketchToPBDLService implements DesignToPBDLService { + @override + Future callPBDL(MainInfo info) async { + return PBDL.fromSketch( + info.designFilePath, + outputPath: p.join(info.genProjectPath, 'assets'), + ); + } + + @override + DesignType designType = DesignType.SKETCH; +} diff --git a/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart b/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart index 08431075..9f2816d1 100644 --- a/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_semantic_generation_service.dart @@ -1,39 +1,39 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_deny_list_helper.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; +// import 'package:parabeac_core/design_logic/design_node.dart'; +// import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_deny_list_helper.dart'; +// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; +// import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; -/// PBSemanticInterpretationService: -/// Interprets certain SketchNodes and converts them into PBIntermediateNode based on certain Semantic Rules; indirect or direct semantics. Furthermore, it removes any SketchNode that are in the DenyList -/// Input: SketchNode -/// Output: PBIntermediateNode, null (No Semantics found that matches that SketchNode), or DenyListNode if the node is part of a DenyList set in the configuration. +// /// PBSemanticInterpretationService: +// /// Interprets certain SketchNodes and converts them into PBIntermediateNode based on certain Semantic Rules; indirect or direct semantics. Furthermore, it removes any SketchNode that are in the DenyList +// /// Input: SketchNode +// /// Output: PBIntermediateNode, null (No Semantics found that matches that SketchNode), or DenyListNode if the node is part of a DenyList set in the configuration. -class PBSemanticGenerationService { - PBSemanticGenerationService({this.currentContext}); +// class PBSemanticGenerationService implements PBGenerationService { +// PBSemanticGenerationService({this.currentContext}); - /// Return DenyListNode if found in the deny List. Return null if there were no semantic node found. Return any other type of PBIntermediateNode if we can tell from direct or indirect semantics. - PBIntermediateNode checkForSemantics(DesignNode node) { - PBIntermediateNode convertedNode; - convertedNode = _checkDirectSemantics(node); - if (convertedNode != null) { - return convertedNode; - } - return convertedNode; - } +// /// Return DenyListNode if found in the deny List. Return null if there were no semantic node found. Return any other type of PBIntermediateNode if we can tell from direct or indirect semantics. +// PBIntermediateNode checkForSemantics(DesignNode node) { +// PBIntermediateNode convertedNode; +// convertedNode = _checkDirectSemantics(node); +// if (convertedNode != null) { +// return convertedNode; +// } +// return convertedNode; +// } - PBIntermediateNode _checkDirectSemantics(DesignNode node) { - PBIntermediateNode convertedNode; +// PBIntermediateNode _checkDirectSemantics(DesignNode node) { +// PBIntermediateNode convertedNode; - convertedNode = PBDenyListHelper().returnDenyListNodeIfExist(node); - if (convertedNode != null) { - return convertedNode; - } +// convertedNode = PBDenyListHelper().returnDenyListNodeIfExist(node); +// if (convertedNode != null) { +// return convertedNode; +// } - return PBPluginListHelper().returnAllowListNodeIfExists(node); - } +// return PBPluginListHelper().returnAllowListNodeIfExists(node); +// } - @override - PBContext currentContext; -} +// @override +// PBContext currentContext; +// } diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index e942eb57..bd3c49d3 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -55,13 +55,15 @@ class PBSharedInterAggregationService { // add Designer Warning here, not even sure if this is the designers fault or not log.warning('UUID: $targetUUID not found in searchNodeByUUID'); } - if ((prop.value != null) && - (prop.type == PBSharedInstanceIntermediateNode)) { + if ((prop.value != null) && (prop.type == 'symbolID')) { + prop.value.currentContext = rootChildNode.currentContext; + ///if the [PBSharedMasterNode] contains [PBSharedInstanceIntermediateNode] as parameters ///then its going gather the information of its [PBSharedMasterNode]. gatherSharedValues(prop.value); } } + sharedMasterNode.overridableProperties .removeWhere((prop) => prop == null || prop.value == null); } @@ -92,18 +94,6 @@ class PBSharedInterAggregationService { return; } if (masterNode?.SYMBOL_ID == instanceIntermediateNode?.SYMBOL_ID) { - instanceIntermediateNode.sharedParamValues = - instanceIntermediateNode.sharedParamValues.map((v) { - for (var symParam in masterNode.overridableProperties) { - if (symParam.propertyName == v.overrideName) { - return PBSharedParameterValue( - symParam.type, v.value, symParam.UUID, symParam.propertyName); - } - } - return null; - }).toList() - ..removeWhere((v) => v == null || v.value == null); - instanceIntermediateNode.currentContext .addDependent(masterNode.currentContext.tree); @@ -115,5 +105,4 @@ class PBSharedInterAggregationService { PBSharedMasterNode _searchMasterNode(String masterUUID) => _symbolStorage.getSharedMasterNodeBySymbolID(masterUUID); - } diff --git a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart index 4300afa8..875b16f8 100644 --- a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart @@ -30,19 +30,21 @@ class PBSymbolLinkerService extends AITHandler{ PBIntermediateNode rootIntermediateNode; stack.add(rootNode); - while(stack.isNotEmpty){ + while (stack.isNotEmpty) { var currentNode = stack.removeLast(); - if(currentNode is PBLayoutIntermediateNode){ - currentNode.children.forEach(stack.add); - } else if (currentNode is PBVisualIntermediateNode && currentNode.child != null){ - stack.add(currentNode.child); - } - - if(currentNode is PBSharedMasterNode){ + // Traverse `currentNode's` attributes and add to stack + currentNode.attributes.forEach((attribute) { + attribute.attributeNodes.forEach((node) { + node.currentContext ??= currentNode.currentContext; + stack.add(node); + }); + }); + + if (currentNode is PBSharedMasterNode) { await _symbolStorage.addSharedMasterNode(currentNode); - _aggregationService.gatherSharedParameters(currentNode, currentNode.child); - - } else if (currentNode is PBSharedInstanceIntermediateNode){ + _aggregationService.gatherSharedParameters( + currentNode, currentNode.child); + } else if (currentNode is PBSharedInstanceIntermediateNode) { await _symbolStorage.addSharedInstance(currentNode); _aggregationService.gatherSharedValues(currentNode); } diff --git a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart index 8cff18ab..277cf89f 100644 --- a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart @@ -1,157 +1,153 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/design_logic/group_node.dart'; -import 'package:parabeac_core/design_logic/pb_shared_instance_design_node.dart'; -import 'package:parabeac_core/design_logic/pb_shared_master_node.dart'; -import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; -import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/input/sketch/services/positional_cleansing_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_deny_list_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/node_tuple.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_deny_list_helper.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; - -/// Takes a SketchNodeTree and begins generating PBNode interpretations. For each node, the node is going to pass through the PBSemanticInterpretationService which checks if the node should generate a specific PBIntermediateNode based on the semantics that it contains. -/// Input: SketchNodeTree -/// Output: PBIntermediateNodeTree -class PBVisualGenerationService{ - - PositionalCleansingService _positionalCleansingService; - - PBStateManagementHelper smHelper; - - /// Boolean that is `true` if the [VisualGenerationService] - /// is currently processing a state management node - bool ignoreStates = false; - - PBVisualGenerationService() { - _positionalCleansingService = PositionalCleansingService(); - smHelper = PBStateManagementHelper(); - } - - DesignNode _positionalOffsetAdjustment(DesignNode designNode){ - // Only do positional cleansing for non-state nodes, since those nodes - // have already been through this service - if(designNode != null && !ignoreStates){ - return _positionalCleansingService.eliminateOffset(designNode); - } - return designNode; - } - - /// Builds and returns intermediate tree by breadth depth first. - /// @return Returns the root node of the intermediate tree. - Future getIntermediateTree(DesignNode originalRoot, PBContext currentContext) async { - if (originalRoot == null) { - return Future.value(null); - } - var tree = PBIntermediateTree(originalRoot.name); - originalRoot = _positionalOffsetAdjustment(originalRoot); - - PBPluginListHelper().initPlugins(currentContext); - - var queue = []; - queue.add(NodeTuple(originalRoot, null)); - while (queue.isNotEmpty) { - var currentNode = queue.removeAt(0); - - if (currentNode.designNode?.isVisible ?? true) { - PBIntermediateNode result; - // Check semantics - result = PBDenyListHelper() - .returnDenyListNodeIfExist(currentNode.designNode); - - if (result is PBDenyListNode) { - } else { - result = PBPluginListHelper() - .returnAllowListNodeIfExists(currentNode.designNode); - - /// Generate general intermediate node if still null. - /// needs to be assigned to [original], because [symbolMaster] needs to be registered to SymbolMaster - - if (result == null || - currentNode.designNode is PBSharedInstanceDesignNode || - currentNode.designNode is PBSharedMasterDesignNode) { - result = await currentNode.designNode.interpretNode(currentContext); - } - - // Interpret state management node - if (!ignoreStates && - smHelper.isValidStateNode(result.name) && - (currentNode.designNode.name != - currentNode.convertedParent?.name ?? - true) && - result is PBSharedMasterNode) { - if (smHelper.isDefaultNode(result)) { - smHelper.interpretStateManagementNode(result); - } else { - smHelper.interpretStateManagementNode(result); - continue; - } - } - - if (currentNode.convertedParent != null) { - _addToParent(currentNode.convertedParent, result); - } - - // If we haven't assigned the tree.rootNode, this must be the first node, aka root node. - tree.rootNode ??= result; - if(tree.rootNode != null){ - _extractScreenSize(tree.rootNode, currentContext); - } - - - if (result != null) { - // Add next depth to queue. - if (currentNode.designNode is GroupNode && - (currentNode.designNode as GroupNode).children != null && - (currentNode.designNode as GroupNode).children.isNotEmpty) { - for (var child - in (currentNode.designNode as GroupNode).children) { - queue.add(NodeTuple(child, result)); - } - } - } - } - } - } - // TODO: This should be replaced for something more optimal or done in some other class - if (originalRoot.prototypeNodeUUID != null) { - var prototypeNode = PrototypeNode(originalRoot.prototypeNodeUUID); - var destHolder = PBDestHolder( - tree.rootNode.topLeftCorner, - tree.rootNode.bottomRightCorner, - tree.rootNode.UUID, - prototypeNode, - tree.rootNode.currentContext); - destHolder.addChild(tree.rootNode); - tree.rootNode = destHolder; - return Future.value(tree); - } - return Future.value(tree); - } - - ///Sets the size of the UI element. - /// - ///We are assuming that since the [tree.rootNode] contains all of the nodes - ///then it should represent the biggest screen size that encapsulates the entire UI elements. - void _extractScreenSize(PBIntermediateNode rootNode, PBContext currentContext) { - if ((currentContext.screenBottomRightCorner == null && - currentContext.screenTopLeftCorner == null) || - (currentContext.screenBottomRightCorner != - rootNode.bottomRightCorner || - currentContext.screenTopLeftCorner != - rootNode.bottomRightCorner)) { - currentContext.screenBottomRightCorner = - rootNode.bottomRightCorner; - currentContext.screenTopLeftCorner = rootNode.topLeftCorner; - } - } - - void _addToParent(PBIntermediateNode parentNode, - PBIntermediateNode convertedChildNode) => - parentNode.addChild(convertedChildNode); -} +// import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; +// import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; +// import 'package:parabeac_core/interpret_and_optimize/entities/pb_deny_list_node.dart'; +// import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; +// import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_deny_list_helper.dart'; +// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; +// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; +// import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; + +// /// Takes a SketchNodeTree and begins generating PBNode interpretations. For each node, the node is going to pass through the PBSemanticInterpretationService which checks if the node should generate a specific PBIntermediateNode based on the semantics that it contains. +// /// Input: SketchNodeTree +// /// Output: PBIntermediateNodeTree +// class PBVisualGenerationService implements PBGenerationService { + +// @override +// PBContext currentContext; + +// PBStateManagementHelper smHelper; + +// PBIntermediateNode originalRoot; + +// /// Boolean that is `true` if the [VisualGenerationService] +// /// is currently processing a state management node +// bool _ignoreStates; + +// /// Constructor for PBVisualGenerationService, must include the root SketchNode +// PBVisualGenerationService(originalRoot, +// {this.currentContext, bool ignoreStates = false}) { +// _ignoreStates = ignoreStates; +// // Only do positional cleansing for non-state nodes, since those nodes +// // have already been through this service +// // if (!_ignoreStates) { +// // _positionalCleansingService = PositionalCleansingService(); +// // this.originalRoot = +// // _positionalCleansingService.eliminateOffset(originalRoot); +// // } else { +// // this.originalRoot = originalRoot; +// // } + +// smHelper = PBStateManagementHelper(); +// } + +// /// Builds and returns intermediate tree by breadth depth first. +// /// @return Returns the root node of the intermediate tree. +// Future getIntermediateTree() async { +// if (originalRoot == null) { +// return Future.value(null); +// } +// PBPluginListHelper().initPlugins(currentContext); + +// var queue = []; +// PBIntermediateNode rootIntermediateNode; +// queue.add(NodeTuple(originalRoot, null)); +// while (queue.isNotEmpty) { +// var currentNode = queue.removeAt(0); + +// if (currentNode.designNode?.isVisible ?? true) { +// PBIntermediateNode result; +// // Check semantics +// result = PBDenyListHelper() +// .returnDenyListNodeIfExist(currentNode.designNode); + +// if (result is PBDenyListNode) { +// } else { +// result = PBPluginListHelper() +// .returnAllowListNodeIfExists(currentNode.designNode); + +// /// Generate general intermediate node if still null. +// /// needs to be assigned to [original], because [symbolMaster] needs to be registered to SymbolMaster + +// if (result == null || +// currentNode.designNode is PBSharedInstanceDesignNode || +// currentNode.designNode is PBSharedMasterDesignNode) { +// result = await currentNode.designNode.interpretNode(currentContext); +// } + +// // Interpret state management node +// if (!_ignoreStates && +// smHelper.isValidStateNode(result.name) && +// (currentNode.designNode.name != +// currentNode.convertedParent?.name ?? +// true) && +// result is PBSharedMasterNode) { +// if (smHelper.isDefaultNode(result)) { +// smHelper.interpretStateManagementNode(result); +// } else { +// smHelper.interpretStateManagementNode(result); +// continue; +// } +// } + +// if (currentNode.convertedParent != null) { +// _addToParent(currentNode.convertedParent, result); +// } + +// // If we haven't assigned the rootIntermediateNode, this must be the first node, aka root node. +// rootIntermediateNode ??= result; + +// if (result != null) { +// // Add next depth to queue. +// if (currentNode.designNode is GroupNode && +// (currentNode.designNode as GroupNode).children != null && +// (currentNode.designNode as GroupNode).children.isNotEmpty) { +// for (var child +// in (currentNode.designNode as GroupNode).children) { +// queue.add(NodeTuple(child, result)); +// } +// } +// } +// } +// } +// } +// // TODO: This should be replaced for something more optimal or done in some other class +// if (originalRoot.prototypeNodeUUID != null) { +// var prototypeNode = PrototypeNode(originalRoot.prototypeNodeUUID); +// var destHolder = PBDestHolder( +// rootIntermediateNode.topLeftCorner, +// rootIntermediateNode.bottomRightCorner, +// rootIntermediateNode.UUID, +// prototypeNode, +// rootIntermediateNode.currentContext); +// destHolder.addChild(rootIntermediateNode); +// return destHolder; +// } +// if (rootIntermediateNode != null) { +// _extractScreenSize(rootIntermediateNode); +// } +// return rootIntermediateNode; +// } + +// ///Sets the size of the UI element. +// /// +// ///We are assuming that since the [rootIntermediateNode] contains all of the nodes +// ///then it should represent the biggest screen size that encapsulates the entire UI elements. +// void _extractScreenSize(PBIntermediateNode rootIntermediateNode) { +// if ((currentContext.screenBottomRightCorner == null && +// currentContext.screenTopLeftCorner == null) || +// (currentContext.screenBottomRightCorner != +// rootIntermediateNode.bottomRightCorner || +// currentContext.screenTopLeftCorner != +// rootIntermediateNode.bottomRightCorner)) { +// currentContext.screenBottomRightCorner = +// rootIntermediateNode.bottomRightCorner; +// currentContext.screenTopLeftCorner = rootIntermediateNode.topLeftCorner; +// } +// } + +// void _addToParent(PBIntermediateNode parentNode, +// PBIntermediateNode convertedChildNode) => +// parentNode.addChild(convertedChildNode); +// } diff --git a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart index 0f04f869..e90a55c1 100644 --- a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart +++ b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart @@ -1,17 +1,22 @@ -import 'package:parabeac_core/design_logic/pb_style.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/intermediate_border_info.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/directed_state_graph.dart'; +import 'package:json_annotation/json_annotation.dart'; +part 'intermediate_auxillary_data.g.dart'; + +@JsonSerializable(explicitToJson: true) class IntermediateAuxiliaryData { + @JsonKey(ignore: true) DirectedStateGraph stateGraph; - /// Info relating to a elements borders, currently just in a map format. - Map borderInfo; + /// Info relating to a elements borders. + @JsonKey(ignore: true) + IntermediateBorderInfo borderInfo; /// The background color of the element. - String color; - - /// the style of the element (which can be overridden) - PBStyle style; + @JsonKey(fromJson: ColorUtils.pbColorFromJsonFills, name: 'fills') + PBColor color; IntermediateAuxiliaryData({ this.stateGraph, @@ -19,4 +24,13 @@ class IntermediateAuxiliaryData { }) { stateGraph ??= DirectedStateGraph(); } + + factory IntermediateAuxiliaryData.fromJson(Map json) => + _$IntermediateAuxiliaryDataFromJson(json) + ..borderInfo = json['borders'].isNotEmpty + ? IntermediateBorderInfo.fromJson(json['borders'][0]) + : IntermediateBorderInfo( + isBorderOutlineVisible: false, borderRadius: 0); + + Map toJson() => _$IntermediateAuxiliaryDataToJson(this); } diff --git a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.g.dart b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.g.dart new file mode 100644 index 00000000..8a9dcb9c --- /dev/null +++ b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'intermediate_auxillary_data.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +IntermediateAuxiliaryData _$IntermediateAuxiliaryDataFromJson( + Map json) { + return IntermediateAuxiliaryData( + alignment: json['alignment'] as Map, + color: ColorUtils.pbColorFromJsonFills( + json['fills'] as List>), + ); +} + +Map _$IntermediateAuxiliaryDataToJson( + IntermediateAuxiliaryData instance) => + { + 'alignment': instance.alignment, + 'fills': instance.color?.toJson(), + }; diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart index a596a56a..5d22086b 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart @@ -1,24 +1,8 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; -import 'package:parabeac_core/input/sketch/helper/symbol_node_mixin.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - class PBSymbolInstanceOverridableValue { final Type type; final String UUID; final dynamic value; - String get friendlyName => SN_UUIDtoVarName[PBInputFormatter.findLastOf(UUID, '/')] ?? 'noname'; - PBSymbolInstanceOverridableValue(this.UUID, this.value, this.type); - - static String _typeToJson(type) { - return {'Type': type.toString()}.toString(); - } - - static Type _typeFromJson(jsonType) { - //TODO: return a more specified Type - return PBIntermediateNode; - } } diff --git a/lib/main.dart b/lib/main.dart index 51c42c4c..67e48bf3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,25 +1,25 @@ import 'dart:convert'; import 'dart:io'; -import 'package:parabeac_core/controllers/design_controller.dart'; -import 'package:parabeac_core/controllers/figma_controller.dart'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/controllers/sketch_controller.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; +import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart'; import 'package:quick_log/quick_log.dart'; -import 'package:sentry/sentry.dart'; import 'package:uuid/uuid.dart'; import 'package:http/http.dart' as http; import 'package:args/args.dart'; -import 'controllers/controller.dart'; +import 'controllers/interpret.dart'; import 'controllers/main_info.dart'; import 'package:yaml/yaml.dart'; import 'package:path/path.dart' as p; -var controllers = [ - FigmaController(), - SketchController(), - DesignController() +final designToPBDLServices = [ + SketchToPBDLService(), + FigmaToPBDLService(), ]; ///sets up parser @@ -89,10 +89,24 @@ ${parser.usage} throw UnsupportedError('We have yet to support this DesignType! '); } - var controller = controllers.firstWhere( - (controller) => controller.designType == processInfo.designType); - await controller.setup(); - controller.convertFile(); + var pbdlService = designToPBDLServices.firstWhere( + (service) => service.designType == processInfo.designType, + ); + var pbdl = await pbdlService.callPBDL(processInfo); + var intermediateProject = await Interpret( + configuration: MainInfo().configuration, + ).interpretAndOptimize(pbdl); + + var projectGenFuture = await FlutterProjectBuilder.createFlutterProject( + processInfo.projectName, + projectDir: processInfo.outputPath); + + var fpb = FlutterProjectBuilder( + MainInfo().configuration.generationConfiguration, + project: intermediateProject, + pageWriter: PBFlutterWriter()); + + await fpb.genProjectFiles(projectGenFuture.item1); exitCode = 0; } @@ -125,11 +139,11 @@ void collectArguments(ArgResults arguments) { info.projectName ??= arguments['project-name']; /// If outputPath is empty, assume we are outputting to design file path - info.outputPath = - arguments['out'] ?? p.dirname(info.designFilePath ?? Directory.current.path); + info.outputPath = arguments['out'] ?? + p.dirname(info.designFilePath ?? Directory.current.path); info.exportPBDL = arguments['export-pbdl'] ?? false; - + /// In the future when we are generating certain dart files only. /// At the moment we are only generating in the flutter project. info.pngPath = p.join(info.genProjectPath, 'assets/images'); @@ -223,7 +237,7 @@ void addToAmplitude() async { }); await http.post( - lambdaEndpt, + Uri.parse(lambdaEndpt), headers: {HttpHeaders.contentTypeHeader: 'application/json'}, body: body, ); diff --git a/pbdl b/pbdl new file mode 160000 index 00000000..be8bad26 --- /dev/null +++ b/pbdl @@ -0,0 +1 @@ +Subproject commit be8bad265ff46e82e1324174e8a0ddfbe2da9727 diff --git a/pubspec.yaml b/pubspec.yaml index 2c6673dc..9e8a18d2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,22 +7,23 @@ environment: sdk: ">=2.7.0 <3.0.0" dependencies: - archive: ^2.0.11 + archive: ^3.1.2 json_serializable: ^3.5.0 build_runner: ^1.10.0 mockito: ^4.1.1 hex: ^0.1.2 build: ^1.3.0 logger: ^0.8.3 - uuid: ^2.1.0 + uuid: ^3.0.0 quick_log: ^1.1.3 sentry: ^3.0.0 http2: ^1.0.1 recase: "^3.0.0" tuple: ^1.0.3 - azblob: ^1.0.3 path: ^1.6.0 file: ^6.1.2 + pbdl: + path: ./pbdl dev_dependencies: pedantic: ^1.8.0 From 0626a85d1ae3fc3583db74ef00ea93d34ca86640 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 11 Aug 2021 18:15:22 -0600 Subject: [PATCH 282/404] WIP MERGED & REFACTORED Rectangle frame, UUID, along with other attributes in the PBIntermediateNode. --- build.yaml | 4 +- lib/controllers/controller.dart | 140 ------------------ lib/controllers/interpret.dart | 123 ++++++--------- lib/eggs/custom_egg.dart | 25 +--- lib/eggs/injected_app_bar.dart | 27 ++-- lib/eggs/injected_back_arrow.dart | 15 +- lib/eggs/injected_tab.dart | 24 ++- lib/eggs/injected_tab_bar.dart | 15 +- .../generators/plugins/pb_plugin_node.dart | 22 +-- .../symbols/pb_instancesym_gen.dart | 3 +- .../prototyping/pb_dest_holder.dart | 8 +- .../pb_prototype_aggregation_service.dart | 21 +-- .../prototyping/pb_prototype_node.dart | 4 +- .../prototyping/pb_prototype_node.g.dart | 2 +- .../entities/alignments/flexible.dart | 15 +- .../entities/alignments/injected_align.dart | 28 +--- .../alignments/injected_positioned.dart | 21 +-- .../entities/alignments/padding.dart | 12 +- .../entities/alignments/spacer.dart | 14 +- .../entities/inherited_bitmap.dart | 42 ++---- .../entities/inherited_bitmap.g.dart | 19 ++- .../entities/inherited_circle.dart | 96 ++---------- .../entities/inherited_circle.g.dart | 29 ++-- .../entities/inherited_container.dart | 45 ++---- .../entities/inherited_container.g.dart | 23 ++- .../entities/inherited_oval.dart | 33 +---- .../entities/inherited_oval.g.dart | 19 ++- .../entities/inherited_polygon.dart | 34 +---- .../entities/inherited_polygon.g.dart | 19 ++- .../entities/inherited_scaffold.dart | 52 +++---- .../entities/inherited_scaffold.g.dart | 27 +++- .../entities/inherited_shape_group.dart | 34 ++--- .../entities/inherited_shape_group.g.dart | 19 ++- .../entities/inherited_shape_path.dart | 33 ++--- .../entities/inherited_shape_path.g.dart | 19 ++- .../entities/inherited_star.dart | 84 ++--------- .../entities/inherited_star.g.dart | 19 ++- .../entities/inherited_text.dart | 50 +++---- .../entities/inherited_text.g.dart | 19 ++- .../entities/inherited_triangle.dart | 33 ++--- .../entities/inherited_triangle.g.dart | 19 ++- .../entities/injected_container.dart | 32 +--- .../entities/injected_container.g.dart | 35 +++-- .../entities/layouts/column.dart | 25 ++-- .../entities/layouts/row.dart | 30 ++-- .../rules/container_constraint_rule.dart | 7 +- .../entities/layouts/rules/handle_flex.dart | 29 ++-- .../entities/layouts/stack.dart | 2 +- .../layouts/temp_group_layout_node.dart | 31 ++-- .../layouts/temp_group_layout_node.g.dart | 13 +- .../entities/pb_deny_list_node.dart | 10 +- .../entities/pb_shared_instance.dart | 45 ++---- .../entities/pb_shared_instance.g.dart | 13 +- .../entities/pb_shared_master_node.dart | 43 ++---- .../entities/pb_shared_master_node.g.dart | 13 +- .../pb_alignment_intermediate_node.dart | 2 - .../subclasses/pb_intermediate_node.dart | 81 ++++++++-- .../subclasses/pb_intermediate_node.g.dart | 11 +- .../pb_layout_intermediate_node.dart | 7 +- .../pb_visual_intermediate_node.dart | 13 +- .../abstract_intermediate_node_factory.dart | 28 ++-- .../helpers/align_strategy.dart | 8 +- .../helpers/child_strategy.dart | 20 ++- .../helpers/pb_deny_list_helper.dart | 2 +- .../helpers/pb_plugin_list_helper.dart | 37 ++--- .../helpers/pb_state_management_linker.dart | 29 ++-- .../pb_alignment_generation_service.dart | 2 +- .../pb_constraint_generation_service.dart | 2 +- .../services/pb_generation_service.dart | 27 ---- .../pb_layout_generation_service.dart | 10 +- .../services/pb_plugin_control_service.dart | 2 +- .../services/pb_symbol_linker_service.dart | 2 +- .../intermediate_auxillary_data.dart | 3 + .../intermediate_auxillary_data.g.dart | 3 +- .../pb_symbol_master_params.dart | 9 +- lib/main.dart | 31 ++-- .../services/interpret_test.dart | 2 +- 77 files changed, 808 insertions(+), 1141 deletions(-) delete mode 100644 lib/controllers/controller.dart delete mode 100644 lib/interpret_and_optimize/entities/subclasses/pb_alignment_intermediate_node.dart delete mode 100644 lib/interpret_and_optimize/services/pb_generation_service.dart diff --git a/build.yaml b/build.yaml index 88eb98c1..75f0b11d 100644 --- a/build.yaml +++ b/build.yaml @@ -1,5 +1,5 @@ targets: - parabeac_core: + $default: builders: parabeac_core|json_serializable: generate_for: @@ -10,7 +10,7 @@ targets: options: any_map: false checked: false - create_factory: true + create_factory: false create_to_json: true disallow_unrecognized_keys: false explicit_to_json: false diff --git a/lib/controllers/controller.dart b/lib/controllers/controller.dart deleted file mode 100644 index ea85158c..00000000 --- a/lib/controllers/controller.dart +++ /dev/null @@ -1,140 +0,0 @@ -import 'dart:async'; - -import 'package:parabeac_core/controllers/interpret.dart'; -import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; -import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; -import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; -import 'package:parabeac_core/input/helper/asset_processing_service.dart'; -import 'package:parabeac_core/input/helper/azure_asset_service.dart'; -import 'package:parabeac_core/input/helper/design_project.dart'; -import 'package:quick_log/quick_log.dart'; -import 'dart:convert'; -import 'dart:io'; -import 'package:meta/meta.dart'; -import 'main_info.dart'; -import 'package:path/path.dart' as p; - -abstract class Controller { - /// Represents an identifier for the current [Controller] at runtime. - /// - /// The main way of using this is to identify what [Controller] is going to be - /// used based on the [designType] within the `main.dart` file - DesignType get designType; - - var log; - - Controller() { - log = Logger(runtimeType.toString()); - } - - /// Gathering all the necessary information for the [Controller] to function - /// properly - /// - /// Most, if not all, of the information will come from the [MainInfo] class. - Future setup() { - var processInfo = MainInfo(); - - /// This is currently a workaround for PB-Nest. This - /// code usually was in the `main.dart`, however, I aggregated all - /// the calls in the default [setup] method for the [Controller] - if (processInfo.pbdlPath != null) { - var pbdl = File(processInfo.pbdlPath).readAsStringSync(); - processInfo.pbdf = json.decode(pbdl); - } - } - - @protected - - /// Mainly used by the subclasses to convert the [designProject] to flutter code. - /// - /// There is a seperation of the methods because some of the [Controller]s need - /// to generate the [designProject] based on the parameters pased to - void convert(DesignProject designProject, - [AssetProcessingService apService]) async { - var processInfo = MainInfo(); - var configuration = processInfo.configuration; - var indexFileFuture = Future.value(); - - /// IN CASE OF JSON ONLY - if (processInfo.exportPBDL) { - return stopAndToJson(designProject, apService); - } - var fileSystemAnalyzer = FileSystemAnalyzer(processInfo.genProjectPath); - fileSystemAnalyzer.addFileExtension('.dart'); - - if (!(await fileSystemAnalyzer.projectExist())) { - await FlutterProjectBuilder.createFlutterProject(processInfo.projectName, - projectDir: processInfo.outputPath); - } else { - indexFileFuture = fileSystemAnalyzer.indexProjectFiles(); - } - - Interpret().init(processInfo.genProjectPath, configuration); - - var pbProject = await Interpret().interpretAndOptimize( - designProject, processInfo.projectName, processInfo.genProjectPath); - - var fpb = FlutterProjectBuilder( - MainInfo().configuration.generationConfiguration, fileSystemAnalyzer, - project: pbProject, pageWriter: PBFlutterWriter()); - - await indexFileFuture; - await fpb.genProjectFiles(processInfo.genProjectPath); - } - - void convertFile( - {AssetProcessingService apService, DesignProject designProject}); - - /// Method that returns the given path and ensures - /// it ends with a / - String verifyPath(String path) { - if (path.endsWith('/')) { - return path; - } else { - return '$path/'; - } - } - - Future stopAndToJson( - DesignProject project, AssetProcessingService apService) async { - var uuids = processRootNodeUUIDs(project, apService); - // Process rootnode UUIDs - await apService.processRootElements(uuids); - project.projectName = MainInfo().projectName; - var projectJson = project.toPBDF(); - projectJson['azure_container_uri'] = AzureAssetService().getContainerUri(); - var encodedJson = json.encode(projectJson); - File('${verifyPath(MainInfo().outputPath)}${project.projectName}.json') - .writeAsStringSync(encodedJson); - log.info( - 'Created PBDL JSON file at ${verifyPath(MainInfo().outputPath)}${project.projectName}.json'); - } - - /// Iterates through the [project] and returns a list of the UUIDs of the - /// rootNodes - Map processRootNodeUUIDs( - DesignProject project, AssetProcessingService apService) { - var result = {}; - - for (var page in project.pages) { - for (var screen in page.screens) { - screen.imageURI = AzureAssetService().getImageURI('${screen.id}.png'); - result[screen.id] = { - 'width': screen.designNode.boundaryRectangle.width, - 'height': screen.designNode.boundaryRectangle.height - }; - } - } - - for (var page in project.miscPages) { - for (var screen in page.screens) { - result[screen.id] = { - 'width': screen.designNode.boundaryRectangle.width, - 'height': screen.designNode.boundaryRectangle.height - }; - } - } - - return result; - } -} diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 9e379bc9..000aded7 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -17,7 +17,6 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_constraint_generation_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; @@ -28,37 +27,46 @@ import 'package:tuple/tuple.dart'; import 'package:path/path.dart' as p; class Interpret { - var log = Logger('Interpret'); + Logger log; Interpret._internal(); static final Interpret _interpret = Interpret._internal(); - factory Interpret({PBConfiguration configuration}) { - _interpret.configuration ??= configuration; + factory Interpret() { + _interpret.log = Logger(_interpret.runtimeType.toString()); _interpret._pbPrototypeLinkerService ??= PBPrototypeLinkerService(); return _interpret; } - PBProject _pbProject; PBPrototypeLinkerService _pbPrototypeLinkerService; - PBConfiguration configuration; - void init(String projectName, PBConfiguration configuration) { - this.configuration ??= configuration; - log = Logger(runtimeType.toString()); - // _interpret._pbSymbolLinkerService = PBSymbolLinkerService(); - // _interpret._pbPrototypeLinkerService = PBPrototypeLinkerService(); - } + final List aitHandlers = [ + PBSymbolLinkerService(), + PBPluginControlService(), + PBLayoutGenerationService(), + PBConstraintGenerationService(), + PBAlignGenerationService() + ]; + + Future interpretAndOptimize( + PBDLProject project, PBConfiguration configuration, + {List handlers, + PBContext context, + AITServiceBuilder aitServiceBuilder}) async { + handlers ??= aitHandlers; + context ??= PBContext(configuration); + + aitServiceBuilder ??= AITServiceBuilder(context, aitHandlers); - Future interpretAndOptimize(PBDLProject project) async { - _pbProject = PBProject.fromJson(project.toJson()); + var _pbProject = PBProject.fromJson(project.toJson()); + context.project = _pbProject; _pbProject.projectAbsPath = p.join(MainInfo().outputPath, MainInfo().projectName); _pbProject.forest = await Future.wait(_pbProject.forest - .map((tree) async => await _generateScreen(tree)) + .map((tree) => aitServiceBuilder.build(tree: tree)) .toList()); _pbProject.forest.removeWhere((element) => element == null); @@ -67,24 +75,6 @@ class Interpret { return _pbProject; } - - Future _generateScreen(DesignScreen designScreen) async { - var currentContext = PBContext(configuration); - currentContext.project = _pb_project; - - var aitServices = [ - PBVisualGenerationService().getIntermediateTree, - PBSymbolLinkerService(), - PBPluginControlService(), - PBLayoutGenerationService(), - PBConstraintGenerationService(), - PBAlignGenerationService() - ]; - - var builder = - AITServiceBuilder(currentContext, designScreen.designNode, aitServices); - return builder.build(); - } } class AITServiceBuilder { @@ -101,11 +91,11 @@ class AITServiceBuilder { /// [Tuple2.item2] is the actual [AITHandler] final List _transformations = []; - final DesignNode designNode; - - AITServiceBuilder(this._context, this.designNode, [List transformations]) { + AITServiceBuilder(this._context, + [List transformations, PBIntermediateTree tree]) { log = Logger(runtimeType.toString()); _stopwatch = Stopwatch(); + _intermediateTree = tree; if (transformations != null) { transformations.forEach(addTransformation); @@ -121,8 +111,7 @@ class AITServiceBuilder { id ??= transformation.runtimeType.toString(); if (transformation is AITHandler) { _transformations.add(Tuple2(id, transformation.handleTree)); - } else if (transformation is AITNodeTransformation || - transformation is PBDLConversion) { + } else if (transformation is AITNodeTransformation) { _transformations.add(Tuple2(id, transformation)); } return this; @@ -133,46 +122,14 @@ class AITServiceBuilder { return _transformations.any((transformation) => transformation.item2 is! AITHandler && transformation.item2 is! AITNodeTransformation && - transformation.item2 is! PBDLConversion && transformation.item2 is! AITTransformation); } - Future _pbdlConversion(PBDLConversion conversion) async { - try { - _stopwatch.start(); - log.fine('Converting ${designNode.name} to AIT'); - _intermediateTree = await conversion(designNode, _context); - - assert(_intermediateTree != null, - 'All PBDL conversions should yield a IntermediateTree'); - _context.tree = _intermediateTree; - _stopwatch.stop(); - log.fine( - 'Finished with ${designNode.name} (${_stopwatch.elapsedMilliseconds}'); - return _intermediateTree; - } catch (e) { - MainInfo().captureException(e); - log.error('PBDL Conversion was not possible because of - \n$e'); - - exit(1); - } - } - - Future build() async { - var pbdlConversion = _transformations - .firstWhere((transformation) => transformation.item2 is PBDLConversion) - .item2; - if (pbdlConversion == null) { - throw Error(); - } - _transformations.removeWhere((element) => element.item2 is PBDLConversion); - await _pbdlConversion(pbdlConversion); - - if (_intermediateTree == null || _intermediateTree.rootNode == null) { - log.warning( - 'Skipping ${designNode.name} as either $PBIntermediateTree or $PBIntermediateTree.rootNode is null'); - return Future.value(_intermediateTree); + Future build({PBIntermediateTree tree}) async { + if (_intermediateTree == null && tree == null) { + throw NullThrownError(); } + _intermediateTree ??= tree; var treeName = _intermediateTree.name; log.fine('Transforming $treeName ...'); @@ -210,3 +167,21 @@ class AITServiceBuilder { return _intermediateTree; } } + +/// Abstract class for Generatiion Services +/// so they all have the current context +abstract class AITHandler { + Logger logger; + + /// Delegates the tranformation/modification to the current [AITHandler] + Future handleTree( + PBContext context, PBIntermediateTree tree); + AITHandler() { + logger = Logger(runtimeType.toString()); + } +} + +typedef AITTransformation = Future Function( + PBContext, PBIntermediateTree); +typedef AITNodeTransformation = Future Function( + PBContext, PBIntermediateNode); diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 60385ab1..860d629c 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -1,13 +1,13 @@ +import 'dart:math'; + import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:uuid/uuid.dart'; import 'package:recase/recase.dart'; @@ -16,34 +16,23 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; CustomEgg( - Point topLeftCorner, - Point bottomRightCorner, + String UUID, + Rectangle frame, String name, { PBContext currentContext, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name) { + }) : super(UUID, frame, currentContext, name) { addAttribute(PBAttribute('child')); generator = CustomEggGenerator(); } - @override - void addChild(PBIntermediateNode node) { - getAttributeNamed('child').attributeNode = node; - } - - @override - void alignChild() { - // Don't do anything - } - @override void extractInformation(PBIntermediateNode incomingNode) { // TODO: implement extractInformation } @override - PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, - PBIntermediateNode originalRef) { - return CustomEgg(topLeftCorner, bottomRightCorner, + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + return CustomEgg(originalRef.name, frame, originalRef.name.replaceAll('', '').pascalCase); } } diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index cefc463b..55cb2df3 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -27,10 +27,9 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { PBIntermediateNode get trailingItem => getAttributeNamed('actions')?.attributeNode; - InjectedAppbar( - Point topLeftCorner, Point bottomRightCorner, String UUID, String name, + InjectedAppbar(String UUID, Rectangle frame, String name, {PBContext currentContext}) - : super(topLeftCorner, bottomRightCorner, currentContext, name) { + : super(UUID, frame, currentContext, name) { generator = PBAppBarGenerator(); addAttribute(PBAttribute('leading')); addAttribute(PBAttribute('title')); @@ -56,10 +55,8 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { } @override - PBEgg generatePluginNode( - Point topLeftCorner, Point bottomRightCorner, originalRef) { - return InjectedAppbar( - topLeftCorner, bottomRightCorner, UUID, originalRef.name, + PBEgg generatePluginNode(Rectangle frame, originalRef) { + return InjectedAppbar(UUID, frame, originalRef.name, currentContext: currentContext); } @@ -71,18 +68,22 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override void extractInformation(PBIntermediateNode incomingNode) {} } -class CustomAppBarAlignment extends AlignStrategy{ + +class CustomAppBarAlignment extends AlignStrategy { @override void align(PBContext context, InjectedAppbar node) { - /// This align only modifies middleItem - var tempNode = InjectedContainer(node.middleItem.bottomRightCorner, - node.middleItem.topLeftCorner, node.middleItem.name, node.middleItem.UUID, - currentContext: node.currentContext, constraints: node.middleItem.constraints) - ..addChild(node.middleItem); + /// This align only modifies middleItem + var tempNode = InjectedContainer( + node.middleItem.UUID, + node.middleItem.frame, + name: node.middleItem.name, + currentContext: node.currentContext, + )..addChild(node.middleItem); node.getAttributeNamed('title').attributeNode = tempNode; } } + class PBAppBarGenerator extends PBGenerator { PBAppBarGenerator() : super(); diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index efd0de5a..9177a0f5 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -8,32 +8,27 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { - @override String semanticName = ''; - + @override ChildrenStrategy childrenStrategy = NoChildStrategy(); @override AlignStrategy alignStrategy = NoAlignment(); - InjectedBackArrow( - Point topLeftCorner, Point bottomRightCorner, String UUID, String name, + InjectedBackArrow(String UUID, Rectangle frame, String name, {PBContext currentContext}) - : super(topLeftCorner, bottomRightCorner, currentContext, name) { + : super(UUID, frame, currentContext, name) { generator = PBBackArrowGenerator(); } - @override void extractInformation(PBIntermediateNode incomingNode) {} @override - PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, - PBIntermediateNode originalRef) { - return InjectedBackArrow( - topLeftCorner, bottomRightCorner, UUID, originalRef.name, + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + return InjectedBackArrow(UUID, frame, originalRef.name, currentContext: currentContext); } } diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index eb2538e8..888aacfc 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -22,14 +22,17 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { ChildrenStrategy childrenStrategy = OneChildStrategy('child'); Tab( - Point topLeftCorner, - Point bottomRightCorner, + String UUID, + Rectangle frame, String name, { - UUID, PBContext currentContext, this.prototypeNode, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID) { + }) : super( + UUID, + frame, + currentContext, + name, + ) { generator = PBTabGenerator(); } @@ -37,19 +40,14 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { String semanticName; @override - PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode) { if (originalNode is PBInheritedIntermediate) { var tab = Tab( - topLeftCorner, - bottomRightCorner, + UUID, + frame, originalNode.name, currentContext: currentContext, - UUID: originalNode != null && - originalNode.UUID != null && - originalNode.UUID.isNotEmpty - ? originalNode.UUID - : Uuid().v4(), prototypeNode: (originalNode as PBInheritedIntermediate).prototypeNode, ); if (originalNode != TempGroupLayoutNode) { diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 34fab539..92862a17 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -21,12 +21,11 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { AlignStrategy alignStrategy = NoAlignment(); InjectedTabBar( - Point topLeftCorner, - Point bottomRightCorner, - String name, - String UUID, { + String UUID, + Rectangle frame, + String name, { PBContext currentContext, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name) { + }) : super(UUID, frame, currentContext, name) { generator = PBTabBarGenerator(); addAttribute(PBAttribute('tabs')); } @@ -51,10 +50,8 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { List layoutInstruction(List layer) {} @override - PBEgg generatePluginNode( - Point topLeftCorner, Point bottomRightCorner, PBIntermediateNode originalRef) { - return InjectedTabBar( - topLeftCorner, bottomRightCorner, originalRef.name, UUID, + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + return InjectedTabBar(UUID, frame, originalRef.name, currentContext: currentContext); } diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index d4a9d31f..52245252 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -7,22 +7,24 @@ abstract class PBEgg extends PBVisualIntermediateNode { /// The allow list semantic name to detect this node. String semanticName; - @override - final String UUID; - - PBEgg(Point topLeftCorner, Point bottomRightCorner, PBContext currentContext, - String name, {this.UUID}) - : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID); + PBEgg( + String UUID, + Rectangle frame, + PBContext currentContext, + String name, + ) : super( + UUID, + frame, + currentContext, + name, + ); /// Override this function if you want to make tree modification prior to the layout service. /// Be sure to return something or you will remove the node from the tree. List layoutInstruction(List layer) => layer; - PBEgg generatePluginNode(Point topLeftCorner, Point bottomRightCorner, - PBIntermediateNode originalNode); + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode); void extractInformation(PBIntermediateNode incomingNode); - } diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 3d9a65ba..2662ca00 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -122,7 +122,8 @@ class PBSymbolInstanceGenerator extends PBGenerator { // Find and reference symbol master if overriding a symbol if (param.type == 'symbolID') { var instance = PBSharedInstanceIntermediateNode( - UUID: param.UUID, + param.UUID, + null, SYMBOL_ID: param.initialValue, name: param.overrideName, overrideValues: [], diff --git a/lib/generation/prototyping/pb_dest_holder.dart b/lib/generation/prototyping/pb_dest_holder.dart index ecc80961..f80867ec 100644 --- a/lib/generation/prototyping/pb_dest_holder.dart +++ b/lib/generation/prototyping/pb_dest_holder.dart @@ -11,11 +11,9 @@ class PBDestHolder extends PBIntermediateNode { @override ChildrenStrategy childrenStrategy = OneChildStrategy('child'); - PBDestHolder(Point topLeftCorner, Point bottomRightCorner, String UUID, - this.pNode, PBContext currentContext) - : super(topLeftCorner, bottomRightCorner, UUID, '', - currentContext: currentContext) { + PBDestHolder( + String UUID, Rectangle frame, this.pNode, PBContext currentContext) + : super(UUID, frame, '', currentContext: currentContext) { generator = PBPrototypeGenerator(pNode); } - } diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index 6608a3ab..e22a7786 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -65,38 +65,25 @@ class PBPrototypeAggregationService { return iNode; } else if (iNode is PBInheritedIntermediate) { var destHolder = PBDestHolder( - iNode.topLeftCorner, - iNode.bottomRightCorner, iNode.UUID, + iNode.frame, (iNode as PBInheritedIntermediate).prototypeNode, iNode.currentContext); destHolder.addChild(iNode); return destHolder; } else if (iNode is PBLayoutIntermediateNode) { var destHolder = PBDestHolder( - iNode.topLeftCorner, - iNode.bottomRightCorner, - iNode.UUID, - iNode.prototypeNode, - iNode.currentContext); + iNode.UUID, iNode.frame, iNode.prototypeNode, iNode.currentContext); destHolder.addChild(iNode); return destHolder; } else if (iNode is InjectedContainer) { var destHolder = PBDestHolder( - iNode.topLeftCorner, - iNode.bottomRightCorner, - iNode.UUID, - iNode.prototypeNode, - iNode.currentContext); + iNode.UUID, iNode.frame, iNode.prototypeNode, iNode.currentContext); destHolder.addChild(iNode); return destHolder; } else if (iNode is Tab) { var destHolder = PBDestHolder( - iNode.topLeftCorner, - iNode.bottomRightCorner, - iNode.UUID, - iNode.prototypeNode, - iNode.currentContext); + iNode.UUID, iNode.frame, iNode.prototypeNode, iNode.currentContext); destHolder.addChild(iNode.child); return destHolder; } else { diff --git a/lib/generation/prototyping/pb_prototype_node.dart b/lib/generation/prototyping/pb_prototype_node.dart index 38d8655c..f8952607 100644 --- a/lib/generation/prototyping/pb_prototype_node.dart +++ b/lib/generation/prototyping/pb_prototype_node.dart @@ -4,13 +4,13 @@ part 'pb_prototype_node.g.dart'; @JsonSerializable(nullable: true) class PrototypeNode { - PrototypeNode(this.destinationUUID, {this.destinationName}); String destinationUUID; String destinationName; + PrototypeNode({this.destinationUUID, this.destinationName}); factory PrototypeNode.fromJson(Map json) => _$PrototypeNodeFromJson(json); Map toJson() => _$PrototypeNodeToJson(this); static PrototypeNode prototypeNodeFromJson(String prototypeNodeUUID) => - PrototypeNode(prototypeNodeUUID); + PrototypeNode(destinationUUID: prototypeNodeUUID); } diff --git a/lib/generation/prototyping/pb_prototype_node.g.dart b/lib/generation/prototyping/pb_prototype_node.g.dart index ec9bfedb..14cae219 100644 --- a/lib/generation/prototyping/pb_prototype_node.g.dart +++ b/lib/generation/prototyping/pb_prototype_node.g.dart @@ -8,7 +8,7 @@ part of 'pb_prototype_node.dart'; PrototypeNode _$PrototypeNodeFromJson(Map json) { return PrototypeNode( - json['destinationUUID'] as String, + destinationUUID: json['destinationUUID'] as String, destinationName: json['destinationName'] as String, ); } diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index 7bddc9c6..97ab6ee9 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -10,27 +10,22 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class Flexible extends PBVisualIntermediateNode { int flex; - @override - ChildrenStrategy childrenStrategy = OneChildStrategy('child'); - - //TODO: Find a way to make currentContext required //without breaking the json serializable Flexible( - String UUID, { + String UUID, + Rectangle frame, { PBContext currentContext, child, this.flex, - Point topLeftCorner, - Point bottomRightCorner, }) : super( - topLeftCorner, - bottomRightCorner, + UUID, + frame, currentContext, '', - UUID: UUID, ) { generator = PBFlexibleGenerator(); + childrenStrategy = OneChildStrategy('child'); this.child = child; } diff --git a/lib/interpret_and_optimize/entities/alignments/injected_align.dart b/lib/interpret_and_optimize/entities/alignments/injected_align.dart index b7fd2162..306b7781 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_align.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_align.dart @@ -1,37 +1,23 @@ +import 'dart:math'; + import 'package:parabeac_core/generation/generators/visual-widgets/pb_align_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; class InjectedAlign extends PBVisualIntermediateNode implements PBInjectedIntermediate { double alignX; double alignY; - InjectedAlign(Point topLeftCorner, Point bottomRightCorner, - PBContext currentContext, String name) - : super(topLeftCorner, bottomRightCorner, currentContext, name) { + InjectedAlign( + String UUID, Rectangle frame, PBContext currentContext, String name) + : super(UUID, frame, currentContext, name) { generator = PBAlignGenerator(); - } - - @override - void addChild(PBIntermediateNode node) { - if (child is TempGroupLayoutNode) { - child.addChild(node); - return; - } - // If there's multiple children add a temp group so that layout service lays the children out. - if (child != null) { - var temp = - TempGroupLayoutNode(currentContext: currentContext, name: node.name); - temp.addChild(child); - temp.addChild(node); - child = temp; - } - child = node; + childrenStrategy = TempChildrenStrategy('child'); } @override diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index 44abfe46..273db7b5 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -8,21 +8,18 @@ import 'dart:math'; class InjectedPositioned extends PBIntermediateNode implements PBInjectedIntermediate { - final PositionedValueHolder valueHolder; - + @override ChildrenStrategy childrenStrategy = OneChildStrategy('child'); InjectedPositioned( - String UUID, - Point tlc, - Point brc, - { + String UUID, + Rectangle frame, { this.valueHolder, PBContext currentContext, PBIntermediateConstraints constraints, - }) : super(tlc ?? Point(0, 0), brc ?? Point(0, 0), UUID, '', + }) : super(UUID, frame, '', currentContext: currentContext, constraints: constraints) { generator = PBPositionedGenerator(overrideChildDim: true); } @@ -41,14 +38,8 @@ class PositionedValueHolder { double height; double width; - PositionedValueHolder({ - this.top, - this.bottom, - this.left, - this.right, - this.height, - this.width - }) { + PositionedValueHolder( + {this.top, this.bottom, this.left, this.right, this.height, this.width}) { // top ??= 0; // bottom ??= 0; // left ??= 0; diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index 1df794e4..0922d51e 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -17,18 +17,21 @@ class Padding extends PBVisualIntermediateNode { @override ChildrenStrategy childrenStrategy = OneChildStrategy('child'); - Padding( String UUID, + Rectangle frame, this.childToParentConstraints, { this.left = 0, this.right = 0, this.top = 0, this.bottom = 0, - Point topLeftCorner, - Point bottomRightCorner, PBContext currentContext, - }) : super(topLeftCorner, bottomRightCorner, currentContext, '', UUID: UUID) { + }) : super( + UUID, + frame, + currentContext, + '', + ) { generator = PBPaddingGen(); } @@ -72,6 +75,7 @@ class Padding extends PBVisualIntermediateNode { bottom = bottom < 0.01 ? 0.0 : bottom; } } + @override PBIntermediateNode fromJson(Map json) => null; } diff --git a/lib/interpret_and_optimize/entities/alignments/spacer.dart b/lib/interpret_and_optimize/entities/alignments/spacer.dart index 98cbaad7..41309051 100644 --- a/lib/interpret_and_optimize/entities/alignments/spacer.dart +++ b/lib/interpret_and_optimize/entities/alignments/spacer.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/generation/generators/visual-widgets/pb_spacer_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; @@ -11,11 +13,13 @@ class Spacer extends PBVisualIntermediateNode { @override ChildrenStrategy childrenStrategy = NoChildStrategy(); - - Spacer(topLeftCorner, bottomRightCorner, String UUID, - {this.flex, PBContext currentContext}) - : super(topLeftCorner, bottomRightCorner, currentContext, '', - UUID: UUID) { + Spacer(String UUID, Rectangle frame, {this.flex, PBContext currentContext}) + : super( + UUID, + frame, + currentContext, + '', + ) { generator = PBSpacerGenerator(); } diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index ee19908c..c8951e0c 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -12,6 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:pbdl/pbdl.dart'; // import 'dart:math'; import 'package:quick_log/quick_log.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -27,10 +28,6 @@ class InheritedBitmap extends PBVisualIntermediateNode fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; - @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - - @JsonKey(name: 'imageReference') String referenceImage; @@ -38,49 +35,40 @@ class InheritedBitmap extends PBVisualIntermediateNode @JsonKey() String type = 'image'; - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) Map originalRef; - InheritedBitmap({ + InheritedBitmap( + String UUID, + Rectangle frame, { this.originalRef, String name, - this.currentContext, + PBContext currentContext, this.referenceImage, - this.bottomRightCorner, - this.topLeftCorner, - this.UUID, this.prototypeNode, this.size, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID ?? '') { + }) : super( + UUID, + frame, + currentContext, + name, + ) { generator = PBBitmapGenerator(); + childrenStrategy = NoChildStrategy(); + ImageReferenceStorage() .addReference(UUID, '${MainInfo().outputPath}assets/images'); } static PBIntermediateNode fromJson(Map json) => _$InheritedBitmapFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart index b6bca16c..79562cfa 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart @@ -8,14 +8,19 @@ part of 'inherited_bitmap.dart'; InheritedBitmap _$InheritedBitmapFromJson(Map json) { return InheritedBitmap( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, referenceImage: json['imageReference'] as String, - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), ) + ..parent = json['parent'] == null + ? null + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String ..children = (json['children'] as List) ?.map((e) => e == null @@ -25,6 +30,10 @@ InheritedBitmap _$InheritedBitmapFromJson(Map json) { ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -34,14 +43,20 @@ InheritedBitmap _$InheritedBitmapFromJson(Map json) { Map _$InheritedBitmapToJson(InheritedBitmap instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'children': instance.children, 'child': instance.child, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'imageReference': instance.referenceImage, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index c94e20d5..5408fd2d 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -1,27 +1,17 @@ -<<<<<<< HEAD import 'dart:math'; -import 'package:parabeac_core/design_logic/design_node.dart'; -======= ->>>>>>> origin/feat/pbdl-interpret import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/intermediate_border_info.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -<<<<<<< HEAD import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -======= import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; ->>>>>>> origin/feat/pbdl-interpret part 'inherited_circle.g.dart'; @@ -34,63 +24,35 @@ class InheritedCircle extends PBVisualIntermediateNode PrototypeNode prototypeNode; @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - - @override -<<<<<<< HEAD - ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); - - InheritedCircle(this.originalRef, Point bottomRightCorner, - Point topLeftCorner, String name, - {PBContext currentContext, Point alignX, Point alignY}) - : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: originalRef.UUID ?? '') { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBBitmapGenerator(); -======= @JsonKey() String type = 'circle'; ->>>>>>> origin/feat/pbdl-interpret - - @override - String UUID; @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; -<<<<<<< HEAD - auxiliaryData.borderInfo = {}; - auxiliaryData.borderInfo['shape'] = 'circle'; -======= - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) Map originalRef; - InheritedCircle({ + InheritedCircle( + String UUID, + Rectangle frame, { this.originalRef, - this.bottomRightCorner, - this.topLeftCorner, String name, - this.currentContext, + PBContext currentContext, Point alignX, Point alignY, - this.UUID, this.size, this.prototypeNode, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID ?? '') { + }) : super( + UUID, + frame, + currentContext, + name, + ) { generator = PBBitmapGenerator(); + childrenStrategy = TempChildrenStrategy('child'); auxiliaryData.borderInfo = IntermediateBorderInfo(); auxiliaryData.borderInfo.shape = 'circle'; @@ -99,42 +61,10 @@ class InheritedCircle extends PBVisualIntermediateNode : null; } - @override - void addChild(PBIntermediateNode node) { - if (child is TempGroupLayoutNode) { - child.addChild(node); - return; - } - // If there's multiple children add a temp group so that layout service lays the children out. - if (child != null) { - var temp = TempGroupLayoutNode( - currentContext: currentContext, - name: node.name, - ); - temp.addChild(child); - temp.addChild(node); - child = temp; - } - child = node; - } - - /// Should add positional info ONLY to parent node. This should only be sent here if the parent and child node is only one-to-one. - /// - /// alignCenterX/y = ((childCenter - parentCenter) / max) if > 0.5 subtract 0.5 if less than 0.5 multiply times -1 - @override - void alignChild() { - var align = - InjectedAlign(topLeftCorner, bottomRightCorner, currentContext, ''); - align.addChild(child); - align.alignChild(); - child = align; ->>>>>>> origin/feat/pbdl-interpret - } - static PBIntermediateNode fromJson(Map json) => _$InheritedCircleFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_circle.g.dart b/lib/interpret_and_optimize/entities/inherited_circle.g.dart index c699c164..ceb11f78 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.g.dart @@ -8,22 +8,23 @@ part of 'inherited_circle.dart'; InheritedCircle _$InheritedCircleFromJson(Map json) { return InheritedCircle( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, - UUID: json['UUID'] as String, size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null + ..parent = json['parent'] == null ? null - : PBIntermediateNode.fromJson(json['child'] as Map) + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int + ..subsemantic = json['subsemantic'] as String + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -33,13 +34,17 @@ InheritedCircle _$InheritedCircleFromJson(Map json) { Map _$InheritedCircleToJson(InheritedCircle instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, - 'children': instance.children, - 'child': instance.child, + 'UUID': instance.UUID, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 76deac92..df4d06ec 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -30,35 +30,14 @@ class InheritedContainer extends PBVisualIntermediateNode @JsonKey(defaultValue: true) bool isBackgroundVisible = true; - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - - ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); - - /// TODO: switch to padding - @override - AlignStrategy alignStrategy = NoAlignment(); - - @override @JsonKey() String type = 'rectangle'; - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) Map originalRef; @@ -67,21 +46,27 @@ class InheritedContainer extends PBVisualIntermediateNode @JsonKey(ignore: true) List get children => null; - InheritedContainer({ + InheritedContainer( + String UUID, + Rectangle frame, { this.originalRef, - this.topLeftCorner, - this.bottomRightCorner, + Rectangle rectangle, String name, double alignX, double alignY, - this.currentContext, + PBContext currentContext, this.isBackgroundVisible = true, - this.UUID, this.size, this.prototypeNode, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID ?? '') { + }) : super( + UUID, + rectangle, + currentContext, + name, + ) { generator = PBContainerGenerator(); + childrenStrategy = TempChildrenStrategy('child'); + //TODO switch alignment to Padding alignment auxiliaryData.alignment = alignX != null && alignY != null ? {'alignX': alignX, 'alignY': alignY} @@ -90,8 +75,8 @@ class InheritedContainer extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) { var container = _$InheritedContainerFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; container.mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/inherited_container.g.dart b/lib/interpret_and_optimize/entities/inherited_container.g.dart index 4817ec21..32efb717 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.g.dart @@ -8,18 +8,24 @@ part of 'inherited_container.dart'; InheritedContainer _$InheritedContainerFromJson(Map json) { return InheritedContainer( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, isBackgroundVisible: json['isBackgroundVisible'] as bool ?? true, - UUID: json['UUID'] as String, size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String - ..child = json['child'] == null + ..parent = json['parent'] == null ? null - : PBIntermediateNode.fromJson(json['child'] as Map) + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int + ..subsemantic = json['subsemantic'] as String + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -29,13 +35,18 @@ InheritedContainer _$InheritedContainerFromJson(Map json) { Map _$InheritedContainerToJson(InheritedContainer instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, - 'child': instance.child, + 'UUID': instance.UUID, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'isBackgroundVisible': instance.isBackgroundVisible, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index 6b7025fb..8020d5b2 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -23,52 +23,33 @@ part 'inherited_oval.g.dart'; @JsonSerializable() class InheritedOval extends PBVisualIntermediateNode implements PBInheritedIntermediate, IntermediateNodeFactory { - @JsonKey(ignore: true) - var log = Logger('Layout Generation Service'); - @override @JsonKey( fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - @override @JsonKey() String type = 'oval'; - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) Map originalRef; - InheritedOval({ + InheritedOval( + String UUID, + Rectangle frame, { this.originalRef, String name, Uint8List image, - this.currentContext, - this.topLeftCorner, - this.bottomRightCorner, - this.UUID, + PBContext currentContext, this.prototypeNode, this.size, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID ?? '') { + }) : super(UUID, frame, currentContext, name) { generator = PBBitmapGenerator(); ImageReferenceStorage().addReferenceAndWrite( @@ -77,8 +58,8 @@ class InheritedOval extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$InheritedOvalFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_oval.g.dart b/lib/interpret_and_optimize/entities/inherited_oval.g.dart index 130bbfe8..d4d6a670 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.g.dart @@ -8,13 +8,18 @@ part of 'inherited_oval.dart'; InheritedOval _$InheritedOvalFromJson(Map json) { return InheritedOval( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), ) + ..parent = json['parent'] == null + ? null + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String ..children = (json['children'] as List) ?.map((e) => e == null @@ -24,6 +29,10 @@ InheritedOval _$InheritedOvalFromJson(Map json) { ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -33,13 +42,19 @@ InheritedOval _$InheritedOvalFromJson(Map json) { Map _$InheritedOvalToJson(InheritedOval instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'children': instance.children, 'child': instance.child, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index 59a41d3c..c865e37d 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -29,60 +29,42 @@ class InheritedPolygon extends PBVisualIntermediateNode fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - - ChildrenStrategy childrenStrategy = NoChildStrategy(); - @override @JsonKey() String type = 'polygon'; - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) Map originalRef; - InheritedPolygon({ + InheritedPolygon(String UUID, Rectangle frame,{ this.originalRef, name, Uint8List image, - this.currentContext, - this.UUID, - this.topLeftCorner, - this.bottomRightCorner, + PBContext currentContext, this.prototypeNode, this.size, }) : super( - topLeftCorner, - bottomRightCorner, + UUID, + frame, currentContext, name, - UUID: UUID ?? '', ) { generator = PBBitmapGenerator(); + childrenStrategy = NoChildStrategy(); + ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); } static PBIntermediateNode fromJson(Map json) => _$InheritedPolygonFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart index 31e1c7db..b8e75830 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart @@ -8,13 +8,18 @@ part of 'inherited_polygon.dart'; InheritedPolygon _$InheritedPolygonFromJson(Map json) { return InheritedPolygon( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'], - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), ) + ..parent = json['parent'] == null + ? null + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String ..children = (json['children'] as List) ?.map((e) => e == null @@ -24,6 +29,10 @@ InheritedPolygon _$InheritedPolygonFromJson(Map json) { ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -33,13 +42,19 @@ InheritedPolygon _$InheritedPolygonFromJson(Map json) { Map _$InheritedPolygonToJson(InheritedPolygon instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'children': instance.children, 'child': instance.child, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index d898d4b1..7f3cb5a4 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; @@ -11,18 +12,20 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attr import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; +import 'package:pbdl/pbdl.dart'; part 'inherited_scaffold.g.dart'; @JsonSerializable() class InheritedScaffold extends PBVisualIntermediateNode with PBColorMixin - implements - /* with GeneratePBTree */ /* PropertySearchable,*/ PBInheritedIntermediate, - IntermediateNodeFactory { + implements PBInheritedIntermediate, IntermediateNodeFactory { @override @JsonKey( fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') @@ -30,29 +33,14 @@ class InheritedScaffold extends PBVisualIntermediateNode @JsonKey(defaultValue: false, name: 'isFlowHome') bool isHomeScreen = false; - AlignStrategy alignStrategy = NoAlignment();//PaddingAlignment(); - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; @override @JsonKey() String type = 'artboard'; - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) PBIntermediateNode get child => getAttributeNamed('body')?.attributeNode; @@ -74,30 +62,24 @@ class InheritedScaffold extends PBVisualIntermediateNode } } - @override - @JsonKey(ignore: true) - List get children => super.children; - @override @JsonKey(ignore: true) Map originalRef; - InheritedScaffold({ + InheritedScaffold( + String UUID, + Rectangle frame, { this.originalRef, - this.topLeftCorner, - this.bottomRightCorner, String name, - this.currentContext, + PBContext currentContext, this.isHomeScreen, - this.UUID, this.prototypeNode, this.size, }) : super( - topLeftCorner, - bottomRightCorner, + UUID, + frame, currentContext, name, - UUID: UUID ?? '', ) { this.name = name ?.replaceAll(RegExp(r'[\W]'), '') @@ -105,6 +87,8 @@ class InheritedScaffold extends PBVisualIntermediateNode generator = PBScaffoldGenerator(); + //TODO switch to padding strategy + // Add body attribute addAttribute(PBAttribute('body')); } @@ -150,8 +134,8 @@ class InheritedScaffold extends PBVisualIntermediateNode } // If there's multiple children add a temp group so that layout service lays the children out. if (child != null) { - var temp = - TempGroupLayoutNode(currentContext: currentContext, name: node.name); + var temp = TempGroupLayoutNode(null, null, + currentContext: currentContext, name: node.name); temp.addChild(child); temp.addChild(node); child = temp; @@ -174,8 +158,8 @@ class InheritedScaffold extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) { var artboard = _$InheritedScaffoldFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; //Map artboard children by calling `addChild` method diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart index 1af175cf..e5ef9646 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart @@ -8,30 +8,51 @@ part of 'inherited_scaffold.dart'; InheritedScaffold _$InheritedScaffoldFromJson(Map json) { return InheritedScaffold( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, isHomeScreen: json['isFlowHome'] as bool ?? false, - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), ) + ..parent = json['parent'] == null + ? null + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( json['style'] as Map) - ..type = json['type'] as String; + ..type = json['type'] as String + ..children = (json['children'] as List) + ?.map((e) => e == null + ? null + : PBIntermediateNode.fromJson(e as Map)) + ?.toList(); } Map _$InheritedScaffoldToJson(InheritedScaffold instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'isFlowHome': instance.isHomeScreen, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, + 'children': instance.children, }; diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index de81a4d6..4655ef72 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -28,29 +28,14 @@ class InheritedShapeGroup extends PBVisualIntermediateNode fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - - ChildrenStrategy childrenStrategy = NoChildStrategy(); @override @JsonKey() String type = 'image'; - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) Map originalRef; @@ -59,24 +44,23 @@ class InheritedShapeGroup extends PBVisualIntermediateNode @JsonKey(ignore: true) List get children => super.children; - InheritedShapeGroup({ + InheritedShapeGroup( + String UUID, + Rectangle frame, { this.originalRef, String name, Uint8List image, - this.currentContext, - this.topLeftCorner, - this.bottomRightCorner, - this.UUID, + PBContext currentContext, this.prototypeNode, this.size, }) : super( - topLeftCorner, - bottomRightCorner, + UUID, + frame, currentContext, name, - UUID: UUID ?? '', ) { generator = PBBitmapGenerator(); + childrenStrategy = NoChildStrategy(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); @@ -84,8 +68,8 @@ class InheritedShapeGroup extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) { var group = _$InheritedShapeGroupFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; group.mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart index a35801e6..e5389bda 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart @@ -8,17 +8,26 @@ part of 'inherited_shape_group.dart'; InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { return InheritedShapeGroup( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), ) + ..parent = json['parent'] == null + ? null + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -29,12 +38,18 @@ InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { Map _$InheritedShapeGroupToJson( InheritedShapeGroup instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'child': instance.child, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 54b48483..a3a0f9d5 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -28,51 +28,36 @@ class InheritedShapePath extends PBVisualIntermediateNode @JsonKey( fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; - ChildrenStrategy childrenStrategy = NoChildStrategy(); - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; @override @JsonKey() String type = 'image'; - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) Map originalRef; - InheritedShapePath({ + InheritedShapePath( + String UUID, + Rectangle frame, { this.originalRef, String name, Uint8List image, - this.currentContext, - this.topLeftCorner, - this.bottomRightCorner, + PBContext currentContext, this.prototypeNode, - this.UUID, this.size, }) : super( - topLeftCorner, - bottomRightCorner, + UUID, + frame, currentContext, name, - UUID: UUID ?? '', ) { generator = PBBitmapGenerator(); + childrenStrategy = NoChildStrategy(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); @@ -121,8 +106,8 @@ class InheritedShapePath extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$InheritedShapePathFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart index 6890d5e0..19d0b494 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart @@ -8,13 +8,18 @@ part of 'inherited_shape_path.dart'; InheritedShapePath _$InheritedShapePathFromJson(Map json) { return InheritedShapePath( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - UUID: json['UUID'] as String, size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), ) + ..parent = json['parent'] == null + ? null + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String ..children = (json['children'] as List) ?.map((e) => e == null @@ -24,6 +29,10 @@ InheritedShapePath _$InheritedShapePathFromJson(Map json) { ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -33,13 +42,19 @@ InheritedShapePath _$InheritedShapePathFromJson(Map json) { Map _$InheritedShapePathToJson(InheritedShapePath instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'children': instance.children, 'child': instance.child, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index c828706d..305d7061 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -8,19 +8,15 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -<<<<<<< HEAD import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -======= import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/value_objects/point.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; ->>>>>>> origin/feat/pbdl-interpret part 'inherited_star.g.dart'; @@ -32,109 +28,47 @@ class InheritedStar extends PBVisualIntermediateNode fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; - @override -<<<<<<< HEAD - PrototypeNode prototypeNode; - - @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - - InheritedStar(this.originalRef, String name, - {Uint8List image, - PBContext currentContext, - PBIntermediateConstraints constraints}) - : super( - Point(originalRef.boundaryRectangle.x, - originalRef.boundaryRectangle.y), - Point( - originalRef.boundaryRectangle.x + - originalRef.boundaryRectangle.width, - originalRef.boundaryRectangle.y + - originalRef.boundaryRectangle.height), - currentContext, - name, - UUID: originalRef.UUID ?? '', - constraints: constraints) { - if (originalRef is DesignNode && originalRef.prototypeNodeUUID != null) { - prototypeNode = PrototypeNode(originalRef?.prototypeNodeUUID); - } - generator = PBBitmapGenerator(); -======= - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - @override @JsonKey() String type = 'star'; - @override - String UUID; ->>>>>>> origin/feat/pbdl-interpret - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) Map originalRef; - InheritedStar({ + InheritedStar( + String UUID, + Rectangle frame, { this.originalRef, name, Uint8List image, - this.currentContext, - this.UUID, - this.topLeftCorner, - this.bottomRightCorner, + PBContext currentContext, this.prototypeNode, this.size, }) : super( - topLeftCorner, - bottomRightCorner, + UUID, + frame, currentContext, name, - UUID: UUID ?? '', ) { generator = PBBitmapGenerator(); + childrenStrategy = NoChildStrategy(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); } -<<<<<<< HEAD -======= - @override - void addChild(PBIntermediateNode node) { - // Hopefully we converted the SVG correctly. Most likely this will get called to add the shapes but this is unnecessary. - if (node is InheritedShapePath) { - return; - } - assert(false, - 'Child with type ${node.runtimeType} could not be added as a child.'); - return; - } - - @override - void alignChild() { - // Images don't have children. - } - static PBIntermediateNode fromJson(Map json) => _$InheritedStarFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override PBIntermediateNode createIntermediateNode(Map json) => InheritedStar.fromJson(json); ->>>>>>> origin/feat/pbdl-interpret } diff --git a/lib/interpret_and_optimize/entities/inherited_star.g.dart b/lib/interpret_and_optimize/entities/inherited_star.g.dart index 8a8a81ae..6d1baa52 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.g.dart @@ -8,13 +8,18 @@ part of 'inherited_star.dart'; InheritedStar _$InheritedStarFromJson(Map json) { return InheritedStar( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'], - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), ) + ..parent = json['parent'] == null + ? null + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String ..children = (json['children'] as List) ?.map((e) => e == null @@ -24,6 +29,10 @@ InheritedStar _$InheritedStarFromJson(Map json) { ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -33,13 +42,19 @@ InheritedStar _$InheritedStarFromJson(Map json) { Map _$InheritedStarToJson(InheritedStar instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'children': instance.children, 'child': instance.child, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index dbc267f2..53b9120f 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -24,9 +24,6 @@ class InheritedText extends PBVisualIntermediateNode @JsonKey(defaultValue: false) bool isTextParameter = false; - @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - @override @JsonKey( fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') @@ -39,24 +36,10 @@ class InheritedText extends PBVisualIntermediateNode @JsonKey() String type = 'text'; - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - @JsonKey(name: 'content') String text; @JsonKey(ignore: true) @@ -76,13 +59,12 @@ class InheritedText extends PBVisualIntermediateNode @JsonKey(ignore: true) Map originalRef; - InheritedText({ + InheritedText( + String UUID, + Rectangle frame, { this.originalRef, name, - this.currentContext, - this.topLeftCorner, - this.bottomRightCorner, - this.UUID, + PBContext currentContext, this.size, this.alignmenttype, this.fontName, @@ -94,9 +76,15 @@ class InheritedText extends PBVisualIntermediateNode this.prototypeNode, this.text, this.textAlignment, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID ?? '') { + }) : super( + UUID, + frame, + currentContext, + name, + ) { generator = PBTextGen(); + childrenStrategy = NoChildStrategy(); + if (text?.contains('\$') ?? false) { text = _sanitizeText(text); } @@ -108,8 +96,8 @@ class InheritedText extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$InheritedTextFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json ..fontSize = InheritedTextPBDLHelper.fontSizeFromJson(json) ..fontName = InheritedTextPBDLHelper.fontNameFromJson(json) @@ -117,16 +105,18 @@ class InheritedText extends PBVisualIntermediateNode ..fontStyle = InheritedTextPBDLHelper.fontStyleFromJson(json) ..textAlignment = InheritedTextPBDLHelper.textAlignmentFromJson(json) ..letterSpacing = InheritedTextPBDLHelper.letterSpacingFromJson(json) - ..auxiliaryData.color = PBColor.fromJson(json['style']['textStyle']['fontColor']); + ..auxiliaryData.color = + PBColor.fromJson(json['style']['textStyle']['fontColor']); @override PBIntermediateNode createIntermediateNode(Map json) { var inheritedText = InheritedText.fromJson(json); // Return an [InheritedContainer] that wraps this text return InheritedContainer( - UUID: inheritedText.UUID, - topLeftCorner: inheritedText.topLeftCorner, - bottomRightCorner: inheritedText.bottomRightCorner, + inheritedText.UUID, + inheritedText.frame, + // topLeftCorner: inheritedText.topLeftCorner, + // bottomRightCorner: inheritedText.bottomRightCorner, name: inheritedText.name, currentContext: inheritedText.currentContext, size: inheritedText.size, diff --git a/lib/interpret_and_optimize/entities/inherited_text.g.dart b/lib/interpret_and_optimize/entities/inherited_text.g.dart index 15daec4b..3be8890c 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.g.dart @@ -8,8 +8,9 @@ part of 'inherited_text.dart'; InheritedText _$InheritedTextFromJson(Map json) { return InheritedText( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'], - UUID: json['UUID'] as String, size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), isTextParameter: json['isTextParameter'] as bool ?? false, @@ -17,6 +18,10 @@ InheritedText _$InheritedTextFromJson(Map json) { json['prototypeNodeUUID'] as String), text: json['content'] as String, ) + ..parent = json['parent'] == null + ? null + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String ..children = (json['children'] as List) ?.map((e) => e == null @@ -26,6 +31,10 @@ InheritedText _$InheritedTextFromJson(Map json) { ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -35,15 +44,21 @@ InheritedText _$InheritedTextFromJson(Map json) { Map _$InheritedTextToJson(InheritedText instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'children': instance.children, 'child': instance.child, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'isTextParameter': instance.isTextParameter, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, 'content': instance.text, }; diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 8561e8d6..3e6b6dc5 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -29,50 +29,35 @@ class InheritedTriangle extends PBVisualIntermediateNode fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') PrototypeNode prototypeNode; - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - ChildrenStrategy childrenStrategy = NoChildStrategy(); @override @JsonKey() String type = 'triangle'; - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - @override @JsonKey(ignore: true) Map originalRef; - InheritedTriangle({ + InheritedTriangle( + String UUID, + Rectangle frame, { this.originalRef, String name, Uint8List image, - this.currentContext, - this.topLeftCorner, - this.bottomRightCorner, - this.UUID, + PBContext currentContext, this.prototypeNode, this.size, }) : super( - topLeftCorner, - bottomRightCorner, + UUID, + frame, currentContext, name, - UUID: UUID ?? '', ) { generator = PBBitmapGenerator(); + childrenStrategy = NoChildStrategy(); ImageReferenceStorage().addReferenceAndWrite( UUID, '${MainInfo().outputPath}assets/images', image); @@ -80,8 +65,8 @@ class InheritedTriangle extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$InheritedTriangleFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart index 7039ebf0..c6332ec8 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart @@ -8,13 +8,18 @@ part of 'inherited_triangle.dart'; InheritedTriangle _$InheritedTriangleFromJson(Map json) { return InheritedTriangle( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( json['boundaryRectangle'] as Map), ) + ..parent = json['parent'] == null + ? null + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String ..children = (json['children'] as List) ?.map((e) => e == null @@ -24,6 +29,10 @@ InheritedTriangle _$InheritedTriangleFromJson(Map json) { ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -33,13 +42,19 @@ InheritedTriangle _$InheritedTriangleFromJson(Map json) { Map _$InheritedTriangleToJson(InheritedTriangle instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'children': instance.children, 'child': instance.child, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index dda2d78c..536ad4b6 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -29,46 +30,29 @@ class InjectedContainer extends PBVisualIntermediateNode @JsonKey(fromJson: PrototypeNode.prototypeNodeFromJson) PrototypeNode prototypeNode; ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); - @override - @JsonKey(fromJson: Point.topLeftFromJson) - Point topLeftCorner; - @override - @JsonKey(fromJson: Point.bottomRightFromJson) - Point bottomRightCorner; - @override @JsonKey() String type = 'injected_container'; - - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson) Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - - InjectedContainer({ - this.bottomRightCorner, - this.topLeftCorner, + InjectedContainer( + UUID, + Rectangle frame, { String name, - this.UUID, double alignX, double alignY, String color, - this.currentContext, + PBContext currentContext, this.prototypeNode, this.size, this.type, }) : super( - topLeftCorner, - bottomRightCorner, + UUID, + frame, currentContext, - name, - UUID: UUID, + name, ) { generator = PBContainerGenerator(); diff --git a/lib/interpret_and_optimize/entities/injected_container.g.dart b/lib/interpret_and_optimize/entities/injected_container.g.dart index 7e023630..8b59ffc0 100644 --- a/lib/interpret_and_optimize/entities/injected_container.g.dart +++ b/lib/interpret_and_optimize/entities/injected_container.g.dart @@ -8,26 +8,23 @@ part of 'injected_container.dart'; InjectedContainer _$InjectedContainerFromJson(Map json) { return InjectedContainer( - bottomRightCorner: Point.bottomRightFromJson( - json['bottomRightCorner'] as Map), - topLeftCorner: - Point.topLeftFromJson(json['topLeftCorner'] as Map), + json['UUID'], + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson(json['prototypeNode'] as String), size: PBIntermediateNode.sizeFromJson(json['size'] as Map), type: json['type'] as String, ) - ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null + ..parent = json['parent'] == null ? null - : PBIntermediateNode.fromJson(json['child'] as Map) + : PBIntermediateNode.fromJson(json['parent'] as Map) + ..treeLevel = json['treeLevel'] as int + ..subsemantic = json['subsemantic'] as String + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -36,15 +33,17 @@ InjectedContainer _$InjectedContainerFromJson(Map json) { Map _$InjectedContainerToJson(InjectedContainer instance) => { + 'parent': instance.parent, + 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, - 'children': instance.children, - 'child': instance.child, + 'UUID': instance.UUID, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNode': instance.prototypeNode, - 'topLeftCorner': instance.topLeftCorner, - 'bottomRightCorner': instance.bottomRightCorner, 'type': instance.type, - 'UUID': instance.UUID, 'size': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/layouts/column.dart b/lib/interpret_and_optimize/entities/layouts/column.dart index a3e77561..55d5587a 100644 --- a/lib/interpret_and_optimize/entities/layouts/column.dart +++ b/lib/interpret_and_optimize/entities/layouts/column.dart @@ -1,3 +1,5 @@ +import 'dart:html'; + import 'package:parabeac_core/generation/generators/layouts/pb_column_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; @@ -28,16 +30,17 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { @override AlignStrategy alignStrategy = ColumnAlignment(); - PBIntermediateColumnLayout( - PBContext currentContext, - {String name}) : super(COLUMN_RULES, COLUMN_EXCEPTIONS, currentContext, name) { + PBIntermediateColumnLayout(PBContext currentContext, Rectangle frame, + {String name}) + : super(null, frame, COLUMN_RULES, COLUMN_EXCEPTIONS, currentContext, + name) { generator = PBColumnGenerator(); } @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { - var col = PBIntermediateColumnLayout(currentContext, name: name); + var col = PBIntermediateColumnLayout(currentContext, null, name: name); col.prototypeNode = prototypeNode; children.forEach((child) => col.addChild(child)); return col; @@ -45,12 +48,9 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { @override void addChild(node) => addChildToLayout(node); - - } -class ColumnAlignment extends AlignStrategy{ - +class ColumnAlignment extends AlignStrategy { /// Invert method for Column alignment void _invertAlignment(PBIntermediateColumnLayout node) { if (node.alignment.isNotEmpty) { @@ -60,6 +60,7 @@ class ColumnAlignment extends AlignStrategy{ node.alignment['mainAxisAlignment'] = tempCrossAxis; } } + @override void align(PBContext context, PBIntermediateColumnLayout node) { node.checkCrossAxisAlignment(); @@ -74,8 +75,8 @@ class ColumnAlignment extends AlignStrategy{ } void _addParallelAlignment(PBIntermediateColumnLayout node) { - var newchildren = handleFlex(true, node.topLeftCorner, node.bottomRightCorner, - node.children?.cast()); + var newchildren = handleFlex(true, node.topLeftCorner, + node.bottomRightCorner, node.children?.cast()); node.replaceChildren(newchildren); } @@ -84,13 +85,11 @@ class ColumnAlignment extends AlignStrategy{ var columnMaxX = node.bottomRightCorner.x; for (var i = 0; i < node.children.length; i++) { - var padding = Padding('', node.children[i].constraints, + var padding = Padding(null, node.frame, node.children[i].constraints, left: node.children[i].topLeftCorner.x - columnMinX ?? 0.0, right: columnMaxX - node.children[i].bottomRightCorner.x ?? 0.0, top: 0.0, bottom: 0.0, - topLeftCorner: node.children[i].topLeftCorner, - bottomRightCorner: node.children[i].bottomRightCorner, currentContext: node.currentContext); padding.addChild(node.children[i]); diff --git a/lib/interpret_and_optimize/entities/layouts/row.dart b/lib/interpret_and_optimize/entities/layouts/row.dart index 7d7c4ba6..ef865411 100644 --- a/lib/interpret_and_optimize/entities/layouts/row.dart +++ b/lib/interpret_and_optimize/entities/layouts/row.dart @@ -27,7 +27,7 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { AlignStrategy alignStrategy = RowAlignment(); PBIntermediateRowLayout(PBContext currentContext, {String name}) - : super(ROW_RULES, ROW_EXCEPTIONS, currentContext, name) { + : super(null, null, ROW_RULES, ROW_EXCEPTIONS, currentContext, name) { generator = PBRowGenerator(); } @@ -49,7 +49,7 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { child0.topLeftCorner.x.compareTo(child1.topLeftCorner.x))); } -class RowAlignment extends AlignStrategy{ +class RowAlignment extends AlignStrategy { @override void align(PBContext context, PBIntermediateRowLayout node) { node.checkCrossAxisAlignment(); @@ -62,9 +62,9 @@ class RowAlignment extends AlignStrategy{ } } - void _addParallelAlignment(PBIntermediateRowLayout node) { - var newchildren = handleFlex(false, node.topLeftCorner, node.bottomRightCorner, - node.children?.cast()); + void _addParallelAlignment(PBIntermediateRowLayout node) { + var newchildren = handleFlex(false, node.topLeftCorner, + node.bottomRightCorner, node.children?.cast()); node.replaceChildren(newchildren); } @@ -75,18 +75,17 @@ class RowAlignment extends AlignStrategy{ if (node.topLeftCorner.y < node.currentContext.screenTopLeftCorner.y) { rowMinY = node.currentContext.screenTopLeftCorner.y; } - if (node.bottomRightCorner.y > node.currentContext.screenBottomRightCorner.y) { + if (node.bottomRightCorner.y > + node.currentContext.screenBottomRightCorner.y) { rowMaxY = node.currentContext.screenBottomRightCorner.y; } for (var i = 0; i < node.children.length; i++) { - var padding = Padding('', node.children[i].constraints, + var padding = Padding(null, node.frame, node.children[i].constraints, top: node.children[i].topLeftCorner.y - rowMinY ?? 0.0, bottom: rowMaxY - node.children[i].bottomRightCorner.y ?? 0.0, left: 0.0, right: 0.0, - topLeftCorner: node.children[i].topLeftCorner, - bottomRightCorner: node.children[i].bottomRightCorner, currentContext: node.currentContext); padding.addChild(node.children[i]); @@ -100,17 +99,16 @@ class RowAlignment extends AlignStrategy{ @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { - var row = PBIntermediateRowLayout(name, Uuid().v4(), - currentContext: currentContext); - row.prototypeNode = prototypeNode; + var row = PBIntermediateRowLayout(currentContext, name: name); + // row.prototypeNode = prototypeNode; children.forEach((child) => row.addChild(child)); return row; } - @override - void sortChildren() => replaceChildren(children - ..sort((child0, child1) => - child0.topLeftCorner.x.compareTo(child1.topLeftCorner.x))); + // @override + // void sortChildren() => replaceChildren(children + // ..sort((child0, child1) => + // child0.topLeftCorner.x.compareTo(child1.topLeftCorner.x))); @override PBIntermediateNode fromJson(Map json) => null; diff --git a/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart index 5b128d14..6e098bcd 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart @@ -9,10 +9,11 @@ class ContainerConstraintRule extends PostConditionRule { dynamic executeAction( PBIntermediateNode currentNode, PBIntermediateNode nextNode) { if (testRule(currentNode, nextNode)) { - var container = InjectedContainer(currentNode.bottomRightCorner, - currentNode.topLeftCorner, currentNode.name, Uuid().v4(), + var container = InjectedContainer(null, currentNode.frame, + name: currentNode.name, currentContext: currentNode.currentContext, - constraints: currentNode.constraints); + // constraints: currentNode.constraints + ); container.addChild(currentNode); return container; } diff --git a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart index aee83d1c..f99c8677 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart @@ -44,15 +44,18 @@ List handleFlex(bool isVertical, Point topLeft, if (spacerLength > 0) { var flex = _calculateFlex(spacerLength, parentLength); resultingChildren.add(Spacer( - isVertical - ? Point( - prevChild.topLeftCorner.x, prevChild.bottomRightCorner.y) - : Point( - prevChild.bottomRightCorner.x, prevChild.topLeftCorner.y), - isVertical - ? Point(child.bottomRightCorner.x, child.topLeftCorner.y) - : Point(child.topLeftCorner.x, child.bottomRightCorner.y), //brc - Uuid().v4(), + null, + Rectangle.fromPoints( + isVertical + ? Point(prevChild.topLeftCorner.x, + prevChild.bottomRightCorner.y) + : Point(prevChild.bottomRightCorner.x, + prevChild.topLeftCorner.y), + isVertical + ? Point(child.bottomRightCorner.x, child.topLeftCorner.y) + : Point(child.topLeftCorner.x, + child.bottomRightCorner.y)), //brc + flex: flex, currentContext: children.first.currentContext)); } @@ -81,10 +84,6 @@ PBIntermediateNode _putChildInFlex( : _calculateWidth(child.topLeftCorner, child.bottomRightCorner); var flex = _calculateFlex(widgetLength.abs(), parentLength.abs()); - return Flexible(Uuid().v4(), - currentContext: child.currentContext, - topLeftCorner: child.topLeftCorner, - bottomRightCorner: child.bottomRightCorner, - child: child, - flex: flex); + return Flexible(null, child.frame, + currentContext: child.currentContext, child: child, flex: flex); } diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index c9e16976..83693d5b 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -24,7 +24,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { PBIntermediateStackLayout(PBContext currentContext, {String name, PBIntermediateConstraints constraints}) - : super(STACK_RULES, [], currentContext, name, constraints: constraints) { + : super(null, null, STACK_RULES, [], currentContext, name, constraints: constraints) { generator = PBStackGenerator(); alignStrategy = PositionedAlignment(); } diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index 2a56ef44..23b124bc 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; @@ -27,37 +29,22 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode @JsonKey() String type = 'group'; - @override - @JsonKey(name: 'UUID') - String UUID; - - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - PBContext currentContext; - @override Map originalRef; - TempGroupLayoutNode({ + TempGroupLayoutNode( + String UUID, + Rectangle frame, { this.originalRef, - this.currentContext, + PBContext currentContext, String name, - this.topLeftCorner, - this.bottomRightCorner, - this.UUID, this.prototypeNode, this.size, - }) : super([], [], currentContext, name); + }) : super(UUID, frame, [], [], currentContext, name); @override void addChild(node) { @@ -80,8 +67,8 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode static PBIntermediateNode fromJson(Map json) { var tempGroup = _$TempGroupLayoutNodeFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; tempGroup.mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart index 798498d9..d7400d94 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart @@ -8,8 +8,9 @@ part of 'temp_group_layout_node.dart'; TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { return TempGroupLayoutNode( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), name: json['name'] as String, - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( @@ -19,6 +20,10 @@ TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -30,11 +35,15 @@ Map _$TempGroupLayoutNodeToJson( TempGroupLayoutNode instance) => { 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'child': instance.child?.toJson(), + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode?.toJson(), 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart index a675b9a1..32c57d7f 100644 --- a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart +++ b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart @@ -8,18 +8,16 @@ import 'package:json_annotation/json_annotation.dart'; /// A node that should not be converted to intermediate. class PBDenyListNode extends PBIntermediateNode { - @override + @override ChildrenStrategy childrenStrategy = NoChildStrategy(); PBDenyListNode( - Point topLeftCorner, - Point bottomRightCorner, - String name, { String UUID, + Rectangle frame, { + String name, PBContext currentContext, }) : super( - topLeftCorner, - bottomRightCorner, UUID, + frame, name, currentContext: currentContext, ); diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index e97e091a..ae1e7e6d 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -49,30 +49,10 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @JsonKey() String type = 'shared_instance'; - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - - @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - - @override - AlignStrategy alignStrategy = NoAlignment();//PaddingAlignment(); - List overrideValues; // quick lookup based on UUID_type Map overrideValuesMap = {}; @@ -81,22 +61,27 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @JsonKey(ignore: true) Map originalRef; - PBSharedInstanceIntermediateNode({ + PBSharedInstanceIntermediateNode( + String UUID, + Rectangle frame, { this.originalRef, this.SYMBOL_ID, this.sharedParamValues, - this.topLeftCorner, - this.bottomRightCorner, - this.currentContext, - this.UUID, + PBContext currentContext, this.prototypeNode, this.size, this.overrideValues, String name, - }) : super(topLeftCorner, bottomRightCorner, currentContext, name, - UUID: UUID) { + }) : super( + UUID, + frame, + currentContext, + name, + ) { generator = PBSymbolInstanceGenerator(); - + + childrenStrategy = NoChildStrategy(); + alignStrategy = NoAlignment(); /// if [sharedParamValues] sets [overrideValues], then only pass one // overrideValues = sharedParamValues.map((v) { // var symOvrValue = @@ -109,8 +94,8 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$PBSharedInstanceIntermediateNodeFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart index 0ac0c838..782cde15 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart @@ -9,13 +9,14 @@ part of 'pb_shared_instance.dart'; PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( Map json) { return PBSharedInstanceIntermediateNode( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), SYMBOL_ID: json['symbolID'] as String, sharedParamValues: (json['overrideValues'] as List) ?.map((e) => e == null ? null : PBSharedParameterValue.fromJson(e as Map)) ?.toList(), - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( @@ -31,6 +32,10 @@ PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -42,8 +47,13 @@ Map _$PBSharedInstanceIntermediateNodeToJson( PBSharedInstanceIntermediateNode instance) => { 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'children': instance.children?.map((e) => e?.toJson())?.toList(), 'child': instance.child?.toJson(), + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'symbolID': instance.SYMBOL_ID, @@ -51,7 +61,6 @@ Map _$PBSharedInstanceIntermediateNodeToJson( instance.sharedParamValues?.map((e) => e?.toJson())?.toList(), 'prototypeNodeUUID': instance.prototypeNode?.toJson(), 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index a3177f1a..cc912ec5 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -22,7 +22,6 @@ part 'pb_shared_master_node.g.dart'; @JsonSerializable(ignoreUnannotated: true, explicitToJson: true) class PBSharedMasterNode extends PBVisualIntermediateNode implements PBInheritedIntermediate, IntermediateNodeFactory { - @override @JsonKey( fromJson: PrototypeNode.prototypeNodeFromJson, name: 'prototypeNodeUUID') @@ -36,35 +35,23 @@ class PBSharedMasterNode extends PBVisualIntermediateNode @JsonKey() String type = 'shared_master'; - @override - @JsonKey(ignore: true) - Point topLeftCorner; - @override - @JsonKey(ignore: true) - Point bottomRightCorner; - - @override - String UUID; - @override @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') Map size; - @override - @JsonKey(ignore: true) - PBContext currentContext; - List parametersDefinition; Map parametersDefsMap = {}; ///The children that makes the UI of the [PBSharedMasterNode]. The children are going to be wrapped ///using a [TempGroupLayoutNode] as the root Node. set children(List children) { - child ??= TempGroupLayoutNode(currentContext: currentContext, name: name); + child ??= TempGroupLayoutNode(null, null, + currentContext: currentContext, name: name); if (child is PBLayoutIntermediateNode) { children.forEach((element) => child.addChild(element)); } else { - child = TempGroupLayoutNode(currentContext: currentContext, name: name) + child = TempGroupLayoutNode(null, null, + currentContext: currentContext, name: name) ..replaceChildren([child, ...children]); } } @@ -78,23 +65,21 @@ class PBSharedMasterNode extends PBVisualIntermediateNode @JsonKey(ignore: true) Map originalRef; - PBSharedMasterNode({ + PBSharedMasterNode( + String UUID, + Rectangle frame, { this.originalRef, this.SYMBOL_ID, String name, - this.topLeftCorner, - this.bottomRightCorner, this.overridableProperties, - this.currentContext, - this.UUID, + PBContext currentContext, this.prototypeNode, this.size, }) : super( - topLeftCorner, - bottomRightCorner, + UUID, + frame, currentContext, name, - UUID: UUID ?? '', ) { overridableProperties ??= []; try { @@ -148,14 +133,12 @@ class PBSharedMasterNode extends PBVisualIntermediateNode } @override - void addChild(node) => - child == null ? child = node : children = [node]; - + void addChild(node) => child == null ? child = node : children = [node]; static PBIntermediateNode fromJson(Map json) => _$PBSharedMasterNodeFromJson(json) - ..topLeftCorner = Point.topLeftFromJson(json) - ..bottomRightCorner = Point.bottomRightFromJson(json) + // ..topLeftCorner = Point.topLeftFromJson(json) + // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json ..mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart index ac36705d..4101b5db 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart @@ -8,6 +8,8 @@ part of 'pb_shared_master_node.dart'; PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { return PBSharedMasterNode( + json['UUID'] as String, + DeserializedRectangle.fromJson(json['frame'] as Map), SYMBOL_ID: json['symbolID'] as String, name: json['name'] as String, overridableProperties: (json['overrideProperties'] as List) @@ -15,7 +17,6 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { ? null : PBSharedParameterProp.fromJson(e as Map)) ?.toList(), - UUID: json['UUID'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), size: PBIntermediateNode.sizeFromJson( @@ -25,6 +26,10 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { ..child = json['child'] == null ? null : PBIntermediateNode.fromJson(json['child'] as Map) + ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( + json['topLeftCorner'] as Map) + ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( + json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -35,13 +40,17 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { Map _$PBSharedMasterNodeToJson(PBSharedMasterNode instance) => { 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, 'child': instance.child?.toJson(), + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode?.toJson(), 'symbolID': instance.SYMBOL_ID, 'type': instance.type, - 'UUID': instance.UUID, 'boundaryRectangle': instance.size, 'overrideProperties': instance.overridableProperties?.map((e) => e?.toJson())?.toList(), diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_alignment_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_alignment_intermediate_node.dart deleted file mode 100644 index 03bd3386..00000000 --- a/lib/interpret_and_optimize/entities/subclasses/pb_alignment_intermediate_node.dart +++ /dev/null @@ -1,2 +0,0 @@ -/// This represents a node that should be a Layout; it contains a set of children arranged in a specific manner. -/// Superclass: PBIntermediateNode \ No newline at end of file diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 61c3d3c3..9feac649 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -23,8 +23,10 @@ part 'pb_intermediate_node.g.dart'; @JsonSerializable( explicitToJson: true, createFactory: false, + ignoreUnannotated: true ) abstract class PBIntermediateNode extends TraversableNode { + @JsonKey(ignore: true) Logger logger; /// A subsemantic is contextual info to be analyzed in or in-between the visual generation & layout generation services. @@ -36,6 +38,7 @@ abstract class PBIntermediateNode extends TraversableNode { @JsonKey() final String UUID; + @JsonKey(ignore: true) PBIntermediateConstraints constraints; /// Map representing the attributes of [this]. @@ -50,8 +53,10 @@ abstract class PBIntermediateNode extends TraversableNode { @override List get children => [child]; + @JsonKey(ignore: true) ChildrenStrategy childrenStrategy = OneChildStrategy('child'); + @JsonKey(ignore: true) AlignStrategy alignStrategy = NoAlignment(); /// Gets the [PBIntermediateNode] at attribute `child` @@ -70,12 +75,21 @@ abstract class PBIntermediateNode extends TraversableNode { } } - @JsonKey(fromJson: Point.topLeftFromJson) + @JsonKey( + fromJson: PBPointLegacyMethod.topLeftFromJson, + toJson: PBPointLegacyMethod.toJson) Point topLeftCorner; - @JsonKey(fromJson: Point.bottomRightFromJson) + @JsonKey( + fromJson: PBPointLegacyMethod.bottomRightFromJson, + toJson: PBPointLegacyMethod.toJson) Point bottomRightCorner; + @JsonKey( + fromJson: DeserializedRectangle.fromJson, + toJson: DeserializedRectangle.toJson) + Rectangle frame; + double get width => (bottomRightCorner.x - topLeftCorner.x).toDouble(); double get height => (bottomRightCorner.y - topLeftCorner.y).toDouble(); @@ -94,8 +108,7 @@ abstract class PBIntermediateNode extends TraversableNode { /// Name of the element if available. String name; - PBIntermediateNode( - this.topLeftCorner, this.bottomRightCorner, this.UUID, this.name, + PBIntermediateNode(this.UUID, this.frame, this.name, {this.currentContext, this.subsemantic, this.constraints}) { logger = Logger(runtimeType.toString()); _attributes = []; @@ -164,22 +177,22 @@ abstract class PBIntermediateNode extends TraversableNode { } /// Adds child to node. - void addChild(node) { + void addChild(PBIntermediateNode node) { childrenStrategy.addChild(this, node); /// Checking the constrains of the [node] being added to the tree, smoe of the /// constrains could be inherited to that section of the sub-tree. } - /// In a recursive manner align the current [this] and the [children] of [this] - /// + /// In a recursive manner align the current [this] and the [children] of [this] + /// /// Its creating a [PBContext.clone] because some values of the [context] are modified - /// when passed to some of the [children]. + /// when passed to some of the [children]. /// For example, the [context.contextConstraints] might /// could contain information from a parent to that particular section of the tree. However, /// because its pass by reference that edits to the context are going to affect the entire [context.tree] and /// not just the sub tree, therefore, we need to [PBContext.clone] to avoid those side effets. - /// + /// /// INFO: there might be a more straight fowards backtracking way of preventing these side effects. void align(PBContext context) { alignStrategy.align(context, this); @@ -188,7 +201,7 @@ abstract class PBIntermediateNode extends TraversableNode { } } - factory PBIntermediateNode.fromJson(Map json) => + factory PBIntermediateNode.fromJson(Map json) => AbstractIntermediateNodeFactory.getIntermediateNode(json); Map toJson() => _$PBIntermediateNodeToJson(this); @@ -232,7 +245,53 @@ extension PBPointLegacyMethod on Point { return y == point.y ? x >= point.x : y >= point.y; } return false; + } + + static Point topLeftFromJson(Map json) { + if (json == null) { + return null; + } + var x, y; + if (json.containsKey('boundaryRectangle')) { + x = json['boundaryRectangle']['x']; + y = json['boundaryRectangle']['y']; + } else { + x = json['x']; + y = json['y']; + } + return Point(x, y); + } + + static Point bottomRightFromJson(Map json) { + if (json == null) { + return null; + } + var x, y; + if (json.containsKey('boundaryRectangle')) { + x = json['boundaryRectangle']['x'] + json['boundaryRectangle']['width']; + y = json['boundaryRectangle']['y'] + json['boundaryRectangle']['height']; + } else { + x = json['x'] + json['width']; + y = json['y'] + json['height']; + } + return Point(x, y); + } + + static Map toJson(Point point) => {'x': point.x, 'y': point.y}; +} +extension DeserializedRectangle on Rectangle { + Point get topLeftCorner => topLeft; + Point get bottomRightCorner => bottomRight; + + static Rectangle fromJson(Map json) { + return Rectangle(json['x'], json['y'], json['width'], json['height']); + } + static Map toJson(Rectangle rectangle) => { + 'height': rectangle.height, + 'width': rectangle.width, + 'x': rectangle.left, + 'y': rectangle.top + }; } -} \ No newline at end of file diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart index ff96c83c..65468eff 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart @@ -10,11 +10,12 @@ Map _$PBIntermediateNodeToJson(PBIntermediateNode instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'children': instance.children?.map((e) => e?.toJson())?.toList(), - 'child': instance.child?.toJson(), - 'topLeftCorner': instance.topLeftCorner?.toJson(), - 'bottomRightCorner': instance.bottomRightCorner?.toJson(), - 'size': instance.size, + 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), + 'bottomRightCorner': + PBPointLegacyMethod.toJson(instance.bottomRightCorner), + 'frame': DeserializedRectangle.toJson(instance.frame), + 'width': instance.width, + 'height': instance.height, 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, }; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index 2e9ebfd5..384b99df 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -37,13 +37,12 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode Map alignment = {}; - PBLayoutIntermediateNode(this._layoutRules, this._exceptions, + PBLayoutIntermediateNode(String UUID, Rectangle frame, this._layoutRules, this._exceptions, PBContext currentContext, String name, - {topLeftCorner, - bottomRightCorner, + { this.prototypeNode, PBIntermediateConstraints constraints}) - : super(topLeftCorner, bottomRightCorner, Uuid().v4(), name, + : super(UUID ?? Uuid().v4(), frame, name, currentContext: currentContext, constraints: constraints) { // Declaring children for layout node addAttribute(PBAttribute('children')); diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart index ec0f490c..f231d841 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart @@ -9,13 +9,10 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; /// Represents a typical node that the end-user could see, it usually has properties such as size and color. It only contains a single child, unlike PBLayoutIntermediateNode that contains a set of children. /// Superclass: PBIntermediateNode abstract class PBVisualIntermediateNode extends PBIntermediateNode { - - - PBVisualIntermediateNode(Point topLeftCorner, Point bottomRightCorner, - PBContext currentContext, String name, - {String UUID, PBIntermediateConstraints constraints}) - : super(topLeftCorner, bottomRightCorner, UUID, name, + + PBVisualIntermediateNode( + String UUID, Rectangle rectangle, PBContext currentContext, String name, + {PBIntermediateConstraints constraints}) + : super(UUID, rectangle, name, currentContext: currentContext, constraints: constraints); - - } diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index 99d73f1d..f9e87070 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -21,20 +21,20 @@ class AbstractIntermediateNodeFactory { static final String INTERMEDIATE_TYPE = 'type'; static final Set _intermediateNodes = { - InheritedBitmap(), - InheritedCircle(), - InheritedContainer(), - InheritedOval(), - InheritedPolygon(), - InheritedScaffold(), - InheritedShapeGroup(), - InheritedShapePath(), - InheritedStar(), - InheritedText(), - InheritedTriangle(), - PBSharedInstanceIntermediateNode(), - PBSharedMasterNode(), - TempGroupLayoutNode(), + InheritedBitmap('$InheritedBitmap', null), + InheritedCircle('$InheritedCircle', null), + InheritedContainer('$InheritedContainer', null), + InheritedOval('$InheritedOval', null), + InheritedPolygon('$InheritedPolygon', null), + InheritedScaffold('$InheritedScaffold', null), + InheritedShapeGroup('$InheritedShapeGroup', null), + InheritedShapePath('$InheritedShapePath', null), + InheritedStar('$InheritedStar', null), + InheritedText('$InheritedText', null), + InheritedTriangle('$InheritedTriangle', null), + PBSharedInstanceIntermediateNode('$PBSharedInstanceIntermediateNode', null), + PBSharedMasterNode('$PBSharedMasterNode', null), + TempGroupLayoutNode('$TempGroupLayoutNode', null), PBIntermediateTree(), }; diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 683907a8..01de98f0 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -44,15 +44,13 @@ abstract class AlignStrategy { class PaddingAlignment extends AlignStrategy { @override void align(PBContext context, PBIntermediateNode node) { - var padding = Padding('', node.child.constraints, + var padding = Padding(null, node.frame, node.child.constraints, left: (node.child.topLeftCorner.x - node.topLeftCorner.x).abs(), right: (node.bottomRightCorner.x - node.child.bottomRightCorner.x).abs(), top: (node.child.topLeftCorner.y - node.topLeftCorner.y).abs(), bottom: (node.child.bottomRightCorner.y - node.bottomRightCorner.y).abs(), - topLeftCorner: node.topLeftCorner, - bottomRightCorner: node.bottomRightCorner, currentContext: node.currentContext); padding.addChild(node.child); node.child = padding; @@ -82,8 +80,8 @@ class PositionedAlignment extends AlignStrategy { } return false; }).forEach((child) { - alignedChildren.add(InjectedPositioned(Uuid().v4(), - child.topLeftCorner.clone(), child.bottomRightCorner.clone(), + alignedChildren.add(InjectedPositioned(null, + child.frame, constraints: child.constraints, currentContext: context, valueHolder: PositionedValueHolder( diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 4275f9c5..17ef14d6 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -2,7 +2,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:quick_log/quick_log.dart'; - abstract class ChildrenStrategy { Logger log; //TODO: will be used in the migrations to attributes @@ -48,8 +47,7 @@ class MultipleChildStrategy extends ChildrenStrategy { } class NoChildStrategy extends ChildrenStrategy { - NoChildStrategy([bool overridable]) - : super('N/A', overridable); + NoChildStrategy([bool overridable]) : super('N/A', overridable); @override void addChild(PBIntermediateNode target, children) { @@ -60,22 +58,22 @@ class NoChildStrategy extends ChildrenStrategy { } } -class TempChildrenStrategy extends ChildrenStrategy{ - TempChildrenStrategy(String attributeName,[ bool overwridable]) : super(attributeName, overwridable); +class TempChildrenStrategy extends ChildrenStrategy { + TempChildrenStrategy(String attributeName, [bool overwridable]) + : super(attributeName, overwridable); @override void addChild(PBIntermediateNode target, children) { - if(target.child is TempGroupLayoutNode){ + if (target.child is TempGroupLayoutNode) { target.child.addChild(children); - } - else if (target.child != null){ - var temp = TempGroupLayoutNode(null, target.currentContext, children.name); + } else if (target.child != null) { + var temp = TempGroupLayoutNode(null, null, + currentContext: target.currentContext, name: children.name); temp.addChild(target.child); temp.addChild(children); temp.parent = target; target.child = temp; - } - else if(children is PBIntermediateNode){ + } else if (children is PBIntermediateNode) { children.parent = target; target.child = children; } diff --git a/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart index 4789d44f..c8afc3b4 100644 --- a/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_deny_list_helper.dart @@ -23,7 +23,7 @@ class PBDenyListHelper { PBDenyListNode returnDenyListNodeIfExist(PBIntermediateNode node) { if (isInDenyListDirect(node)) { - return PBDenyListNode(Point(0, 0), Point(0, 0), ''); + return PBDenyListNode(null, node.frame); } else { return null; } diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index 7aa62ddf..40c0f6de 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -13,13 +13,15 @@ class PBPluginListHelper { static final PBPluginListHelper _instance = PBPluginListHelper._internal(); void initPlugins(PBContext context) { allowListNames = { - '': InjectedTabBar(Point(0, 0), Point(0, 0), Uuid().v4(), '', - currentContext: context), - '': InjectedAppbar(Point(0, 0), Point(0, 0), Uuid().v4(), '', - currentContext: context), - '': Tab(Point(0, 0), Point(0, 0), '', - currentContext: context, UUID: Uuid().v4()), - '': CustomEgg(Point(0, 0), Point(0, 0), ''), + '': InjectedTabBar(null, null, '', currentContext: context), + '': InjectedAppbar(null, null, '', currentContext: context), + '': Tab( + null, + null, + '', + currentContext: context, + ), + '': CustomEgg(null, null, ''), }; } @@ -28,19 +30,21 @@ class PBPluginListHelper { PBPluginListHelper._internal() { allowListNames = { '': InjectedTabBar( - Point(0, 0), - Point(0, 0), - Uuid().v4(), + null, + null, '', ), '': InjectedAppbar( - Point(0, 0), - Point(0, 0), - Uuid().v4(), + null, + null, + '', + ), + '': Tab( + null, + null, '', ), - '': Tab(Point(0, 0), Point(0, 0), '', UUID: Uuid().v4()), - '': CustomEgg(Point(0, 0), Point(0, 0), ''), + '': CustomEgg(null, null, ''), }; } @@ -85,8 +89,7 @@ class PBPluginListHelper { if (node != null) { for (var key in allowListNames.keys) { if (node.name?.contains(key) ?? false) { - return allowListNames[key].generatePluginNode( - node.topLeftCorner, node.bottomRightCorner, node); + return allowListNames[key].generatePluginNode(node.frame, node); } } } diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index efa57d1d..4f227ab6 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -5,7 +5,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_visual_generation_service.dart'; @@ -89,21 +88,19 @@ class PBStateManagementLinker { /// the necessary interpretation services. Future _interpretVariationNode( PBIntermediateNode node) async { - var visualGenerationService = PBVisualGenerationService(); - visualGenerationService.ignoreStates = true; - var builder = AITServiceBuilder( - node.currentContext, (node as PBInheritedIntermediate).originalRef); - builder - .addTransformation(visualGenerationService.getIntermediateTree) - .addTransformation((PBIntermediateTree tree, context) { - /// Making sure the name of the tree was changed back - tree.name = node.name; - }) - .addTransformation( - PBPluginControlService().convertAndModifyPluginNodeTree) - .addTransformation(PBLayoutGenerationService().extractLayouts) - .addTransformation(PBAlignGenerationService().addAlignmentToLayouts); - return builder.build().then((tree) => tree.rootNode); + // var builder = AITServiceBuilder( + // node.currentContext, (node as PBInheritedIntermediate).originalRef); + // builder + // .addTransformation(visualGenerationService.getIntermediateTree) + // .addTransformation((PBIntermediateTree tree, context) { + // /// Making sure the name of the tree was changed back + // tree.name = node.name; + // }) + // .addTransformation( + // PBPluginControlService().convertAndModifyPluginNodeTree) + // .addTransformation(PBLayoutGenerationService().extractLayouts) + // .addTransformation(PBAlignGenerationService().addAlignmentToLayouts); + // return builder.build().then((tree) => tree.rootNode); } } diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index b94533a0..d2d1af89 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -1,8 +1,8 @@ +import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:quick_log/quick_log.dart'; /// PBAlignmentGenerationService: diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index ba28e4a3..11d67f3b 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; @@ -7,7 +8,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; ///tree.where((element) => element != null).toList().reversed.map((e) => e.name).toList() class PBConstraintGenerationService extends AITHandler { diff --git a/lib/interpret_and_optimize/services/pb_generation_service.dart b/lib/interpret_and_optimize/services/pb_generation_service.dart deleted file mode 100644 index 6fe13185..00000000 --- a/lib/interpret_and_optimize/services/pb_generation_service.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:parabeac_core/design_logic/design_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:quick_log/quick_log.dart'; - -/// Abstract class for Generatiion Services -/// so they all have the current context -abstract class AITHandler { - Logger logger; - /// Delegates the tranformation/modification to the current [AITHandler] - Future handleTree( - PBContext context, PBIntermediateTree tree); - AITHandler(){ - logger = Logger(runtimeType.toString()); - } -} - -typedef AITTransformation = Future Function( - PBContext, PBIntermediateTree); -typedef AITNodeTransformation = Future Function( - PBContext, PBIntermediateNode); - -typedef PBDLConversion = Future Function( - DesignNode, PBContext); - - diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index ce803674..4a9cc52c 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart'; @@ -12,7 +13,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:tuple/tuple.dart'; @@ -24,7 +24,6 @@ class PBLayoutGenerationService extends AITHandler { ///The available Layouts that could be injected. final List _availableLayouts = []; - ///[LayoutRule] that check post conditions. final List _postLayoutRules = [ StackReductionVisualRule(), @@ -154,9 +153,10 @@ class PBLayoutGenerationService extends AITHandler { tempGroup, (tempGroup as TempGroupLayoutNode).children[0]) : _replaceNode( tempGroup, - InjectedContainer(tempGroup.bottomRightCorner, - tempGroup.topLeftCorner, tempGroup.name, tempGroup.UUID, - constraints: tempGroup.constraints)); + InjectedContainer( + tempGroup.UUID, tempGroup.frame, name: tempGroup.name, + // constraints: tempGroup.constraints + )); } return tempGroup; } diff --git a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart index 9f15aff0..8009a36f 100644 --- a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart +++ b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; @@ -5,7 +6,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/layer_tuple.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:quick_log/quick_log.dart'; /// Plugin control service traverses the interediate node tree andl looks for nodes that are of type PBPluginNode. diff --git a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart index 875b16f8..16b86eab 100644 --- a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -6,7 +7,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_shared_aggregation_service.dart'; class PBSymbolLinkerService extends AITHandler{ diff --git a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart index e90a55c1..c0cf52c1 100644 --- a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart +++ b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart @@ -10,6 +10,9 @@ class IntermediateAuxiliaryData { @JsonKey(ignore: true) DirectedStateGraph stateGraph; + /// Info relating to the alignment of an element, currently just in a map format. + Map alignment; + /// Info relating to a elements borders. @JsonKey(ignore: true) IntermediateBorderInfo borderInfo; diff --git a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.g.dart b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.g.dart index 8a9dcb9c..b54d94c0 100644 --- a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.g.dart +++ b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.g.dart @@ -9,10 +9,9 @@ part of 'intermediate_auxillary_data.dart'; IntermediateAuxiliaryData _$IntermediateAuxiliaryDataFromJson( Map json) { return IntermediateAuxiliaryData( - alignment: json['alignment'] as Map, color: ColorUtils.pbColorFromJsonFills( json['fills'] as List>), - ); + )..alignment = json['alignment'] as Map; } Map _$IntermediateAuxiliaryDataToJson( diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart index ba7ebebe..b0e1b4ae 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart @@ -9,7 +9,7 @@ import 'dart:math'; ///TODO: Need another class for elements that generate but are not visuals. -class PBSymbolMasterParameter extends PBVisualIntermediateNode +class PBSymbolMasterParameter extends PBIntermediateNode implements PBInjectedIntermediate { final Type type; final String parameterID; @@ -35,7 +35,12 @@ class PBSymbolMasterParameter extends PBVisualIntermediateNode this.bottomRightX, this.bottomRightY, {this.context}) - : super(Point(0, 0), Point(0, 0), context, name); + : super( + null, + null, + name, + currentContext: context, + ); static String _typeToJson(type) { return type.toString(); diff --git a/lib/main.dart b/lib/main.dart index 67e48bf3..77642175 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; @@ -21,6 +22,8 @@ final designToPBDLServices = [ SketchToPBDLService(), FigmaToPBDLService(), ]; +FileSystemAnalyzer fileSystemAnalyzer; +Interpret interpretService; ///sets up parser final parser = ArgParser() @@ -89,24 +92,30 @@ ${parser.usage} throw UnsupportedError('We have yet to support this DesignType! '); } + Future indexFileFuture; + fileSystemAnalyzer = FileSystemAnalyzer(processInfo.genProjectPath); + fileSystemAnalyzer.addFileExtension('.dart'); + + if (!(await fileSystemAnalyzer.projectExist())) { + await FlutterProjectBuilder.createFlutterProject(processInfo.projectName, + projectDir: processInfo.outputPath); + } else { + indexFileFuture = fileSystemAnalyzer.indexProjectFiles(); + } + var pbdlService = designToPBDLServices.firstWhere( (service) => service.designType == processInfo.designType, ); var pbdl = await pbdlService.callPBDL(processInfo); - var intermediateProject = await Interpret( - configuration: MainInfo().configuration, - ).interpretAndOptimize(pbdl); - - var projectGenFuture = await FlutterProjectBuilder.createFlutterProject( - processInfo.projectName, - projectDir: processInfo.outputPath); + var intermediateProject = await interpretService.interpretAndOptimize( + pbdl, MainInfo().configuration); var fpb = FlutterProjectBuilder( - MainInfo().configuration.generationConfiguration, - project: intermediateProject, - pageWriter: PBFlutterWriter()); + MainInfo().configuration.generationConfiguration, fileSystemAnalyzer, + project: intermediateProject, pageWriter: PBFlutterWriter()); - await fpb.genProjectFiles(projectGenFuture.item1); + await indexFileFuture; + await fpb.genProjectFiles(processInfo.genProjectPath); exitCode = 0; } diff --git a/test/lib/interpret_and_optimize/services/interpret_test.dart b/test/lib/interpret_and_optimize/services/interpret_test.dart index 180c1919..ccd26774 100644 --- a/test/lib/interpret_and_optimize/services/interpret_test.dart +++ b/test/lib/interpret_and_optimize/services/interpret_test.dart @@ -86,7 +86,7 @@ void main() { when(project.pages).thenReturn([page]); when(page.getPageItems()).thenReturn([screen]); - when(screen.designNode).thenReturn(artboard); + when(screen.AITree).thenReturn(artboard); when(artboard.children).thenReturn([mockGroup]); when(artboard.isVisible).thenReturn(true); From c052e1c05ea6b1ddfd3a5873cf5cff686599866d Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 11 Aug 2021 19:16:40 -0600 Subject: [PATCH 283/404] MERGE WIP removal of PBAttribute --- lib/controllers/interpret.dart | 65 +++-- lib/eggs/custom_egg.dart | 31 ++- lib/eggs/injected_app_bar.dart | 65 +++-- lib/eggs/injected_back_arrow.dart | 15 +- lib/eggs/injected_tab.dart | 14 +- lib/eggs/injected_tab_bar.dart | 30 +-- .../flutter_project_builder.dart | 77 +++--- .../attribute-helper/pb_size_helper.dart | 33 +-- .../generators/layouts/pb_row_gen.dart | 4 +- .../generators/layouts/pb_scaffold_gen.dart | 6 +- .../generators/layouts/pb_stack_gen.dart | 1 - .../middleware/command_gen_middleware.dart | 19 +- .../generators/middleware/middleware.dart | 14 +- .../state_management/bloc_middleware.dart | 33 +-- .../state_management/provider_middleware.dart | 21 +- .../state_management/riverpod_middleware.dart | 23 +- .../state_management_middleware.dart | 11 +- .../state_management/stateful_middleware.dart | 14 +- .../utils/middleware_utils.dart | 11 +- .../generators/pb_flutter_generator.dart | 7 +- .../generators/pb_generation_manager.dart | 3 +- .../generators/plugins/pb_plugin_node.dart | 2 - .../generators/symbols/pb_mastersym_gen.dart | 12 +- .../pb_file_structure_strategy.dart | 15 +- .../provider_file_structure_strategy.dart | 1 + .../riverpod_file_structure_strategy.dart | 1 + .../pb_generation_configuration.dart | 68 +++--- ...platform_orientation_generation_mixin.dart | 11 +- .../bloc_state_template_strategy.dart | 6 +- .../stateless_template_strategy.dart | 8 +- .../visual-widgets/pb_align_gen.dart | 6 +- .../visual-widgets/pb_container_gen.dart | 17 +- .../visual-widgets/pb_flexible_gen.dart | 6 +- .../visual-widgets/pb_padding_gen.dart | 12 +- .../visual-widgets/pb_positioned_gen.dart | 14 +- .../visual-widgets/pb_text_gen.dart | 8 +- .../prototyping/pb_dest_holder.dart | 8 +- .../pb_prototype_aggregation_service.dart | 49 ++-- .../prototyping/pb_prototype_gen.dart | 5 +- .../pb_prototype_linker_service.dart | 41 ++-- .../prototyping/pb_prototype_storage.dart | 12 +- .../entities/alignments/flexible.dart | 6 +- .../entities/alignments/injected_align.dart | 63 +++-- .../alignments/injected_positioned.dart | 4 +- .../entities/alignments/padding.dart | 47 ++-- .../entities/alignments/spacer.dart | 5 +- .../entities/inherited_bitmap.dart | 23 +- .../entities/inherited_bitmap.g.dart | 31 +-- .../entities/inherited_circle.dart | 11 +- .../entities/inherited_circle.g.dart | 21 +- .../entities/inherited_container.dart | 16 +- .../entities/inherited_container.g.dart | 21 +- .../entities/inherited_oval.dart | 19 +- .../entities/inherited_oval.g.dart | 31 +-- .../entities/inherited_polygon.dart | 19 +- .../entities/inherited_polygon.g.dart | 31 +-- .../entities/inherited_scaffold.dart | 217 +++++++++-------- .../entities/inherited_scaffold.g.dart | 33 +-- .../entities/inherited_shape_group.dart | 13 - .../entities/inherited_shape_group.g.dart | 25 +- .../entities/inherited_shape_path.dart | 10 +- .../entities/inherited_shape_path.g.dart | 31 +-- .../entities/inherited_star.dart | 11 +- .../entities/inherited_star.g.dart | 31 +-- .../entities/inherited_text.dart | 15 +- .../entities/inherited_text.g.dart | 31 +-- .../entities/inherited_triangle.dart | 12 +- .../entities/inherited_triangle.g.dart | 31 +-- .../entities/injected_container.dart | 16 +- .../entities/injected_container.g.dart | 20 +- .../entities/layouts/column.dart | 56 +++-- .../layouts/exceptions/stack_exception.dart | 16 +- .../entities/layouts/row.dart | 72 +++--- .../layouts/rules/axis_comparison_rules.dart | 54 +++-- .../rules/container_constraint_rule.dart | 1 - .../layouts/rules/container_rule.dart | 2 +- .../entities/layouts/rules/handle_flex.dart | 38 +-- .../rules/stack_reduction_visual_rule.dart | 12 +- .../entities/layouts/stack.dart | 21 +- .../layouts/temp_group_layout_node.dart | 17 +- .../layouts/temp_group_layout_node.g.dart | 19 +- .../entities/pb_deny_list_node.dart | 2 - .../entities/pb_shared_instance.dart | 10 +- .../entities/pb_shared_instance.g.dart | 25 +- .../entities/pb_shared_master_node.dart | 36 +-- .../entities/pb_shared_master_node.g.dart | 19 +- .../entities/subclasses/pb_attribute.dart | 30 --- .../subclasses/pb_intermediate_node.dart | 228 ++++++++++-------- .../subclasses/pb_intermediate_node.g.dart | 7 +- .../pb_layout_intermediate_node.dart | 152 ++++++------ .../pb_visual_intermediate_node.dart | 6 +- .../abstract_intermediate_node_factory.dart | 2 +- .../helpers/align_strategy.dart | 53 ++-- .../helpers/child_strategy.dart | 34 +-- .../helpers/pb_context.dart | 40 +-- .../helpers/pb_image_reference_storage.dart | 3 + .../helpers/pb_intermediate_dfs_iterator.dart | 1 - .../pb_intermediate_layer_iterator.dart | 32 +++ .../helpers/pb_intermediate_node_tree.dart | 22 +- .../helpers/pb_plugin_list_helper.dart | 5 +- .../helpers/pb_state_management_linker.dart | 1 - .../intermediate_node_searcher_service.dart | 45 ++-- .../pb_layout_generation_service.dart | 142 ++++++----- ...b_platform_orientation_linker_service.dart | 17 +- .../services/pb_plugin_control_service.dart | 15 +- .../pb_shared_aggregation_service.dart | 9 +- .../services/pb_symbol_linker_service.dart | 41 +--- .../pb_visual_generation_service.dart | 153 ------------ .../pb_symbol_master_params.dart | 24 +- lib/main.dart | 21 +- pbdl | 2 +- 111 files changed, 1294 insertions(+), 1834 deletions(-) delete mode 100644 lib/interpret_and_optimize/entities/subclasses/pb_attribute.dart create mode 100644 lib/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart delete mode 100644 lib/interpret_and_optimize/services/pb_visual_generation_service.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 000aded7..7a43ff2b 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -1,10 +1,9 @@ import 'dart:io'; - +import 'dart:math'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; import 'dart:convert'; - import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_aggregation_service.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; @@ -43,37 +42,36 @@ class Interpret { final List aitHandlers = [ PBSymbolLinkerService(), - PBPluginControlService(), + // PBPluginControlService(), PBLayoutGenerationService(), PBConstraintGenerationService(), PBAlignGenerationService() ]; - Future interpretAndOptimize( - PBDLProject project, PBConfiguration configuration, - {List handlers, - PBContext context, - AITServiceBuilder aitServiceBuilder}) async { + Future interpretAndOptimize( + PBIntermediateTree tree, PBContext context, PBProject project, + {List handlers, AITServiceBuilder aitServiceBuilder}) async { handlers ??= aitHandlers; - context ??= PBContext(configuration); - - aitServiceBuilder ??= AITServiceBuilder(context, aitHandlers); - var _pbProject = PBProject.fromJson(project.toJson()); - context.project = _pbProject; + aitServiceBuilder ??= AITServiceBuilder(aitHandlers); - _pbProject.projectAbsPath = - p.join(MainInfo().outputPath, MainInfo().projectName); + /// This is a workaround for adding missing information to either the [PBContext] or any of the + /// [PBIntermediateNode]s. + aitServiceBuilder.addTransformation( + (PBContext context, PBIntermediateTree tree) { + context.project = project; - _pbProject.forest = await Future.wait(_pbProject.forest - .map((tree) => aitServiceBuilder.build(tree: tree)) - .toList()); - _pbProject.forest.removeWhere((element) => element == null); + /// Assuming that the [tree.rootNode] has the dimensions of the screen. + context.screenFrame = Rectangle.fromPoints( + tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); + context.tree = tree; + tree.context = context; + return Future.value(tree); + }, index: 0, id: 'Assigning $PBContext to $PBIntermediateTree'); - // TODO: do this in just one go - await PBPrototypeAggregationService().linkDanglingPrototypeNodes(); + // await PBPrototypeAggregationService().linkDanglingPrototypeNodes(); - return _pbProject; + return aitServiceBuilder.build(tree: tree, context: context); } } @@ -83,7 +81,6 @@ class AITServiceBuilder { PBIntermediateTree _intermediateTree; set intermediateTree(PBIntermediateTree tree) => _intermediateTree = tree; - final PBContext _context; Stopwatch _stopwatch; /// These are the [AITHandler]s that are going to be transforming @@ -91,8 +88,7 @@ class AITServiceBuilder { /// [Tuple2.item2] is the actual [AITHandler] final List _transformations = []; - AITServiceBuilder(this._context, - [List transformations, PBIntermediateTree tree]) { + AITServiceBuilder([List transformations, PBIntermediateTree tree]) { log = Logger(runtimeType.toString()); _stopwatch = Stopwatch(); _intermediateTree = tree; @@ -107,12 +103,14 @@ class AITServiceBuilder { /// Adding a [transformation] that will be applyed to the [PBIntermediateTree]. The [id] /// is to [log] the [transformation]. - AITServiceBuilder addTransformation(transformation, {String id}) { + AITServiceBuilder addTransformation(transformation, {String id, int index}) { id ??= transformation.runtimeType.toString(); + index ??= _transformations.length; if (transformation is AITHandler) { - _transformations.add(Tuple2(id, transformation.handleTree)); - } else if (transformation is AITNodeTransformation) { - _transformations.add(Tuple2(id, transformation)); + _transformations.insert(index, Tuple2(id, transformation.handleTree)); + } else if (transformation is AITNodeTransformation || + transformation is AITTransformation) { + _transformations.insert(index, Tuple2(id, transformation)); } return this; } @@ -125,7 +123,8 @@ class AITServiceBuilder { transformation.item2 is! AITTransformation); } - Future build({PBIntermediateTree tree}) async { + Future build( + {PBIntermediateTree tree, PBContext context}) async { if (_intermediateTree == null && tree == null) { throw NullThrownError(); } @@ -143,10 +142,10 @@ class AITServiceBuilder { try { if (transformation is AITNodeTransformation) { for (var node in _intermediateTree) { - node = await transformation(_context, node); + node = await transformation(context, node, _intermediateTree); } } else if (transformation is AITTransformation) { - _intermediateTree = await transformation(_context, _intermediateTree); + _intermediateTree = await transformation(context, _intermediateTree); } if (_intermediateTree == null || _intermediateTree.rootNode == null) { @@ -184,4 +183,4 @@ abstract class AITHandler { typedef AITTransformation = Future Function( PBContext, PBIntermediateTree); typedef AITNodeTransformation = Future Function( - PBContext, PBIntermediateNode); + PBContext, PBIntermediateNode, PBIntermediateTree); diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 860d629c..76fa0671 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -5,8 +5,9 @@ import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:uuid/uuid.dart'; @@ -18,11 +19,10 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { CustomEgg( String UUID, Rectangle frame, - String name, { - PBContext currentContext, - }) : super(UUID, frame, currentContext, name) { - addAttribute(PBAttribute('child')); + String name, + ) : super(UUID, frame, name) { generator = CustomEggGenerator(); + childrenStrategy = OneChildStrategy('child'); } @override @@ -32,8 +32,10 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { - return CustomEgg(originalRef.name, frame, + var egg = CustomEgg(originalRef.name, frame, originalRef.name.replaceAll('', '').pascalCase); + originalRef.children.forEach((child) => egg.addChild(child)); + return egg; } } @@ -41,23 +43,20 @@ class CustomEggGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext context) { // TODO: correct import - source.managerData.addImport(FlutterImport( + context.managerData.addImport(FlutterImport( 'egg/${source.name.snakeCase}.dart', MainInfo().projectName, )); - source.currentContext.configuration.generationConfiguration - .fileStructureStrategy + context.configuration.generationConfiguration.fileStructureStrategy .commandCreated(WriteSymbolCommand( - Uuid().v4(), - source.name.snakeCase, - customBoilerPlate(source.name), - relativePath: 'egg', - symbolPath: 'lib', - )); + Uuid().v4(), source.name.snakeCase, customBoilerPlate(source.name), + relativePath: 'egg', + symbolPath: 'lib', + ownership: FileOwnership.DEV)); if (source is CustomEgg) { return ''' ${source.name}( - child: ${source.attributes[0].attributeNode.generator.generate(source.attributes[0].attributeNode, context)} + child: ${source.children[0].generator.generate(source.children[0], context)} ) '''; } diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 55cb2df3..8e6e503d 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -7,57 +7,52 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; - @override - AlignStrategy alignStrategy = CustomAppBarAlignment(); + PBIntermediateNode get leadingItem => getAttributeNamed('leading'); + PBIntermediateNode get middleItem => getAttributeNamed('title'); + PBIntermediateNode get trailingItem => getAttributeNamed('actions'); - @override - List get children => - [leadingItem, middleItem, trailingItem]; - - PBIntermediateNode get leadingItem => - getAttributeNamed('leading')?.attributeNode; - PBIntermediateNode get middleItem => - getAttributeNamed('title')?.attributeNode; - PBIntermediateNode get trailingItem => - getAttributeNamed('actions')?.attributeNode; - - InjectedAppbar(String UUID, Rectangle frame, String name, - {PBContext currentContext}) - : super(UUID, frame, currentContext, name) { + InjectedAppbar( + String UUID, + Rectangle frame, + String name, + ) : super(UUID, frame, name) { generator = PBAppBarGenerator(); - addAttribute(PBAttribute('leading')); - addAttribute(PBAttribute('title')); - addAttribute(PBAttribute('actions')); + alignStrategy = CustomAppBarAlignment(); } @override - void addChild(node) { + void addChild(PBIntermediateNode node) { if (node is PBInheritedIntermediate) { + var attName = 'child'; if (node.name.contains('')) { - getAttributeNamed('leading').attributeNode = node; + attName = 'leading'; } - if (node.name.contains('')) { - getAttributeNamed('actions').attributeNode = node; + attName = 'actions'; } if (node.name.contains('')) { - getAttributeNamed('title').attributeNode = node; + attName = 'title'; } + node.attributeName = attName; + children.add(node); + return; } - return; + super.addChild(node); } @override PBEgg generatePluginNode(Rectangle frame, originalRef) { - return InjectedAppbar(UUID, frame, originalRef.name, - currentContext: currentContext); + return InjectedAppbar( + UUID, + frame, + originalRef.name, + ); } @override @@ -77,10 +72,13 @@ class CustomAppBarAlignment extends AlignStrategy { node.middleItem.UUID, node.middleItem.frame, name: node.middleItem.name, - currentContext: node.currentContext, - )..addChild(node.middleItem); + ) + ..addChild(node.middleItem) + ..attributeName = 'title'; - node.getAttributeNamed('title').attributeNode = tempNode; + var target = + node.children.firstWhere((element) => element.attributeName == 'title'); + target = tempNode; } } @@ -95,10 +93,9 @@ class PBAppBarGenerator extends PBGenerator { buffer.write('AppBar('); - source.attributes.forEach((attribute) { - attribute.attributeNode.currentContext = source.currentContext; + source.children.forEach((child) { buffer.write( - '${attribute.attributeName}: ${_wrapOnBrackets(attribute.attributeNode.generator.generate(attribute.attributeNode, generatorContext), attribute.attributeName == 'actions', attribute.attributeName == 'leading')},'); + '${child.attributeName}: ${_wrapOnBrackets(child.generator.generate(child, generatorContext), child == 'actions', child == 'leading')},'); }); buffer.write(')'); diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index 9177a0f5..8bfff37f 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -17,9 +17,11 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { @override AlignStrategy alignStrategy = NoAlignment(); - InjectedBackArrow(String UUID, Rectangle frame, String name, - {PBContext currentContext}) - : super(UUID, frame, currentContext, name) { + InjectedBackArrow( + String UUID, + Rectangle frame, + String name, + ) : super(UUID, frame, name) { generator = PBBackArrowGenerator(); } @@ -28,8 +30,11 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { - return InjectedBackArrow(UUID, frame, originalRef.name, - currentContext: currentContext); + return InjectedBackArrow( + UUID, + frame, + originalRef.name, + ); } } diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 888aacfc..2673abac 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -8,49 +8,41 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; -import 'package:uuid/uuid.dart'; class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { @override PrototypeNode prototypeNode; - @override - ChildrenStrategy childrenStrategy = OneChildStrategy('child'); - Tab( String UUID, Rectangle frame, String name, { - PBContext currentContext, this.prototypeNode, }) : super( UUID, frame, - currentContext, name, ) { generator = PBTabGenerator(); + childrenStrategy = OneChildStrategy('child'); } @override String semanticName; @override - PBEgg generatePluginNode(Rectangle frame, - PBIntermediateNode originalNode) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode) { if (originalNode is PBInheritedIntermediate) { var tab = Tab( UUID, frame, originalNode.name, - currentContext: currentContext, prototypeNode: (originalNode as PBInheritedIntermediate).prototypeNode, ); - if (originalNode != TempGroupLayoutNode) { + if (originalNode is! TempGroupLayoutNode) { var designNode = _convertWrapper(originalNode); ///Clean the node so that it doesn't get interpreted as a plugin again. diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 92862a17..92a4796f 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -1,5 +1,5 @@ import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; + import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; @@ -15,7 +15,7 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; - List get tabs => getAttributeNamed('tabs').attributeNodes; + List get tabs => getAllAtrributeNamed('tabs'); @override AlignStrategy alignStrategy = NoAlignment(); @@ -23,11 +23,9 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { InjectedTabBar( String UUID, Rectangle frame, - String name, { - PBContext currentContext, - }) : super(UUID, frame, currentContext, name) { + String name, + ) : super(UUID, frame, name) { generator = PBTabBarGenerator(); - addAttribute(PBAttribute('tabs')); } @override @@ -35,14 +33,14 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { if (node is PBInheritedIntermediate) { if (node.name.contains('')) { assert(node is! Tab, 'node should be a Tab'); - getAttributeNamed('tabs') - .attributeNodes - .add(node as PBIntermediateNode); + node.attributeName = 'tab'; + children.add(node); } } if (node is Tab) { - getAttributeNamed('tabs').attributeNodes.add(node); + node.attributeName = 'tab'; + children.add(node); } } @@ -51,8 +49,11 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { - return InjectedTabBar(UUID, frame, originalRef.name, - currentContext: currentContext); + return InjectedTabBar( + UUID, + frame, + originalRef.name, + ); } @override @@ -65,7 +66,7 @@ class PBTabBarGenerator extends PBGenerator { PBTabBarGenerator() : super(); @override - String generate(PBIntermediateNode source, PBContext generatorContext) { + String generate(PBIntermediateNode source, PBContext context) { // generatorContext.sizingContext = SizingValueContext.PointValue; if (source is InjectedTabBar) { var tabs = source.tabs; @@ -77,7 +78,8 @@ class PBTabBarGenerator extends PBGenerator { buffer.write('items:['); for (var i = 0; i < tabs.length; i++) { buffer.write('BottomNavigationBarItem('); - var res = generatorContext.generationManager.generate(tabs[i].child); + var res = context.generationManager + .generate(tabs[i].children.first, context); buffer.write('icon: $res,'); buffer.write('title: Text(""),'); buffer.write('),'); diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index f68f4511..31e21437 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'dart:io'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:path/path.dart' as p; import 'package:archive/archive.dart'; @@ -30,7 +32,7 @@ class FlutterProjectBuilder { /// Logger that prints consoles informatio static Logger log; - PBPageWriter pageWriter; + // PBPageWriter pageWriter; ///The [GenerationConfiguration] that is going to be use in the generation of the code /// @@ -39,16 +41,18 @@ class FlutterProjectBuilder { FileSystemAnalyzer fileSystemAnalyzer; + bool _configured = false; + FlutterProjectBuilder( this.generationConfiguration, this.fileSystemAnalyzer, { this.project, - this.pageWriter, + // this.pageWriter, }) { log = Logger(runtimeType.toString()); fileSystemAnalyzer ??= FileSystemAnalyzer(project.projectAbsPath); - generationConfiguration.pageWriter = pageWriter; + // generationConfiguration.pageWriter = pageWriter; generationConfiguration.fileSystemAnalyzer = fileSystemAnalyzer; } @@ -107,45 +111,34 @@ class FlutterProjectBuilder { }); } - Future genProjectFiles(String genProjectPath, - {List rawImages}) async { - // generate shared Styles if any found - // if (project.sharedStyles != null && - // project.sharedStyles.isNotEmpty && - // MainInfo().exportStyles) { - // try { - // Directory(p.join(genProjectPath, 'lib/document/')) - // .createSync(recursive: true); - - // WriteStyleClasses(genProjectPath); - - // var s = File(p.join(genProjectPath, 'lib/document/shared_props.g.dart')) - // .openWrite(mode: FileMode.write, encoding: utf8); - - // s.write('''${FlutterImport('dart:ui', null)} - // ${FlutterImport('flutter/material.dart', null)} - - // '''); - // for (var sharedStyle in project.sharedStyles) { - // s.write(sharedStyle.generate() + '\n'); - // } - // await s.close(); - // } catch (e) { - // log.error(e.toString()); - // } - // } - await Future.wait(PBStateManagementLinker().stateQueue, eagerError: true); - - await generationConfiguration.generateProject(project); - generationConfiguration - .generatePlatformAndOrientationInstance(project); - - Process.runSync('rm', ['-rf', '.dart_tool/build'], - runInShell: true, - environment: Platform.environment, - workingDirectory: MainInfo().outputPath); - - await formatProject(genProjectPath, projectDir: MainInfo().outputPath); + Future preGenTasks() async { + _configured = true; + await Future.wait([ + Future.wait(PBStateManagementLinker().stateQueue, eagerError: true), + Process.run('rm', ['-rf', '.dart_tool/build'], + runInShell: true, + environment: Platform.environment, + workingDirectory: MainInfo().outputPath), + generationConfiguration.generateProject(project) + ]); + + ; + } + + Future postGenTask() async { + await formatProject(project.projectAbsPath, + projectDir: MainInfo().outputPath); + } + + Future genAITree(PBIntermediateTree tree, PBContext context) async { + if (!_configured) { + /// Avoid changing the [_configured] from here, it might lead to async changes on the var + throw Error(); + } + + await generationConfiguration.generateTree(tree, project, context, true); + await generationConfiguration.generateTree(tree, project, context, false); + generationConfiguration.generatePlatformAndOrientationInstance(project); } } diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index 7e6d82fe..6c69ca62 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -6,29 +6,23 @@ class PBSizeHelper extends PBAttributesHelper { PBSizeHelper() : super(); @override - String generate(PBIntermediateNode source, PBContext generatorContext) { - if (source.currentContext == null) { + String generate(PBIntermediateNode source, PBContext context) { + if (context == null) { print('Tried generating a size but couldn\'t retrieve [currentContext]'); return ''; } final buffer = StringBuffer(); - var body = source.size ?? {}; - double relativeHeight = body['height']; - double relativeWidth = body['width']; + double relativeHeight = source.frame.height; + double relativeWidth = source.frame.width; //Add relative sizing if the widget has context var screenWidth; var screenHeight; - if (source.currentContext.screenTopLeftCorner != null && - source.currentContext.screenBottomRightCorner != null) { - screenWidth = ((source.currentContext.screenTopLeftCorner.x) - - (source.currentContext.screenBottomRightCorner.x)) - .abs(); - screenHeight = ((source.currentContext.screenTopLeftCorner.y) - - (source.currentContext.screenBottomRightCorner.y)) - .abs(); + if (context.screenFrame != null) { + screenWidth = context.screenFrame.width; + screenHeight = context.screenFrame.height; } relativeHeight = @@ -40,25 +34,24 @@ class PBSizeHelper extends PBAttributesHelper { ? relativeWidth / screenWidth : relativeWidth; - if (generatorContext.sizingContext == SizingValueContext.ScaleValue) { + if (context.sizingContext == SizingValueContext.ScaleValue) { var height = source.constraints.fixedHeight != null - ? body['height'].toStringAsFixed(3) + ? relativeHeight.toStringAsFixed(3) : 'MediaQuery.of(context).size.height * ${relativeHeight.toStringAsFixed(3)}'; var width = source.constraints.fixedWidth != null - ? body['width'].toStringAsFixed(3) + ? relativeWidth.toStringAsFixed(3) : 'MediaQuery.of(context).size.width * ${relativeWidth.toStringAsFixed(3)}'; // buffer.write( // 'constraints: BoxConstraints(maxHeight: ${height}, maxWidth: ${width}),'); - } else if (generatorContext.sizingContext == - SizingValueContext.LayoutBuilderValue) { + } else if (context.sizingContext == SizingValueContext.LayoutBuilderValue) { buffer.write( 'width: constraints.maxWidth * ${relativeWidth.toStringAsFixed(3)},'); buffer.write( 'height: constraints.maxHeight * ${relativeHeight.toStringAsFixed(3)},'); } else { - relativeHeight = body['height']; - relativeWidth = body['width']; + // relativeHeight = body['height']; + // relativeWidth = body['width']; if (relativeWidth != null) { buffer.write('width: ${relativeWidth.toStringAsFixed(3)},'); } diff --git a/lib/generation/generators/layouts/pb_row_gen.dart b/lib/generation/generators/layouts/pb_row_gen.dart index 4186e9ff..8a1fadc8 100644 --- a/lib/generation/generators/layouts/pb_row_gen.dart +++ b/lib/generation/generators/layouts/pb_row_gen.dart @@ -7,15 +7,13 @@ class PBRowGenerator extends PBLayoutGenerator { PBRowGenerator() : super(); @override - String generate( - PBIntermediateNode source, PBContext generatorContext) { + String generate(PBIntermediateNode source, PBContext generatorContext) { if (source is PBIntermediateRowLayout) { var buffer = StringBuffer(); var counter = 0; var children = source.children; for (var child in children) { - child.currentContext = source.currentContext; buffer.write(child.generator.generate(child, generatorContext)); var trailing_comma = (counter + 1) == children.length ? '' : ','; buffer.write(trailing_comma); diff --git a/lib/generation/generators/layouts/pb_scaffold_gen.dart b/lib/generation/generators/layouts/pb_scaffold_gen.dart index dafd0e50..87a32781 100644 --- a/lib/generation/generators/layouts/pb_scaffold_gen.dart +++ b/lib/generation/generators/layouts/pb_scaffold_gen.dart @@ -13,10 +13,10 @@ class PBScaffoldGenerator extends PBGenerator { generatorContext.sizingContext = generatorContext.configuration.scaling ? SizingValueContext.ScaleValue : SizingValueContext.PointValue; - var appBar = source.getAttributeNamed('appBar')?.attributeNode; - var body = source.getAttributeNamed('body')?.attributeNode; + var appBar = source.getAttributeNamed('appBar'); + var body = source.getAttributeNamed('body'); var bottomNavBar = - source.getAttributeNamed('bottomNavigationBar')?.attributeNode; + source.getAttributeNamed('bottomNavigationBar'); if (source is InheritedScaffold) { var buffer = StringBuffer(); buffer.write('Scaffold(\n'); diff --git a/lib/generation/generators/layouts/pb_stack_gen.dart b/lib/generation/generators/layouts/pb_stack_gen.dart index 369ef61f..8acc98f7 100644 --- a/lib/generation/generators/layouts/pb_stack_gen.dart +++ b/lib/generation/generators/layouts/pb_stack_gen.dart @@ -14,7 +14,6 @@ class PBStackGenerator extends PBGenerator { if (source.children.isNotEmpty) { buffer.write('\nchildren: ['); for (var index = 0; index < source.children.length; index++) { - source.children[index].currentContext = source.currentContext; var element = source.children[index].generator .generate(source.children[index], generatorContext); buffer.write(element); diff --git a/lib/generation/generators/middleware/command_gen_middleware.dart b/lib/generation/generators/middleware/command_gen_middleware.dart index aac26dfa..1e64e72c 100644 --- a/lib/generation/generators/middleware/command_gen_middleware.dart +++ b/lib/generation/generators/middleware/command_gen_middleware.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:recase/recase.dart'; @@ -27,35 +28,35 @@ class CommandGenMiddleware extends Middleware } @override - Future applyMiddleware(PBIntermediateTree tree) { + Future applyMiddleware(PBIntermediateTree tree, PBContext context) { if (tree == null) { return Future.value(tree); } var command; - _addDependencyImports(tree, packageName); + _addDependencyImports(tree, packageName, context); if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { - getPlatformOrientationName(tree.rootNode); + getPlatformOrientationName(tree.rootNode, context); command = ExportPlatformCommand( tree.UUID, - tree.rootNode.currentContext.tree.data.platform, + context.tree.data.platform, tree.identifier, tree.rootNode.name.snakeCase, - generationManager.generate(tree.rootNode), + generationManager.generate(tree.rootNode, context), ); } else if (tree.isScreen()) { command = WriteScreenCommand( tree.UUID, tree.identifier, tree.name, - generationManager.generate(tree.rootNode), + generationManager.generate(tree.rootNode, context), ); } else { command = WriteSymbolCommand( tree.UUID, tree.identifier, - generationManager.generate(tree.rootNode), + generationManager.generate(tree.rootNode, context), relativePath: tree.name, ); } @@ -69,9 +70,9 @@ class CommandGenMiddleware extends Middleware /// If an import path is found, it will be added to the `tree`'s data. The package format /// for imports is going to be enforced, therefore, [packageName] is going to be /// a required parameter. - void _addDependencyImports(PBIntermediateTree tree, String packageName) { + void _addDependencyImports(PBIntermediateTree tree, String packageName, PBContext context) { var iter = tree.dependentsOn; - var addImport = tree.rootNode.managerData.addImport; + var addImport = context.managerData.addImport; while (iter.moveNext()) { _importProcessor.getFormattedImports( diff --git a/lib/generation/generators/middleware/middleware.dart b/lib/generation/generators/middleware/middleware.dart index fcf74fb2..45d77bf8 100644 --- a/lib/generation/generators/middleware/middleware.dart +++ b/lib/generation/generators/middleware/middleware.dart @@ -2,6 +2,7 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.d import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:recase/recase.dart'; @@ -18,16 +19,19 @@ abstract class Middleware { Middleware(this.generationManager, this.configuration, {this.nextMiddleware}); - String getNameOfNode(PBIntermediateNode node) => ImportHelper.getName(node.name); + String getNameOfNode(PBIntermediateNode node) => + ImportHelper.getName(node.name); /// Applying the [Middleware] logic to the [node]; modifying it or even eliminating it by returning `null`. - Future applyMiddleware(PBIntermediateTree tree) => - handleTree(tree); + Future applyMiddleware( + PBIntermediateTree tree, PBContext context) => + handleTree(tree, context); - Future handleTree(PBIntermediateTree tree) { + Future handleTree( + PBIntermediateTree tree, PBContext context) { return nextMiddleware == null ? Future.value(tree) - : nextMiddleware.applyMiddleware(tree); + : nextMiddleware.applyMiddleware(tree, context); } void addImportToCache(String id, String path) { diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 69e6b3c3..a0633fea 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/generation/generators/value_objects/generator_adap import 'package:parabeac_core/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; @@ -60,9 +61,9 @@ class BLoCMiddleware extends StateManagementMiddleware { } @override - Future handleStatefulNode(PBIntermediateNode node) { - var managerData = node.managerData; - node.currentContext.project.genProjectData + Future handleStatefulNode(PBIntermediateNode node, PBContext context) { + // var managerData = node.managerData; + context.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); var fileStrategy = @@ -72,7 +73,7 @@ class BLoCMiddleware extends StateManagementMiddleware { if (node is PBSharedInstanceIntermediateNode) { var generalStateName = node.functionCallName .substring(0, node.functionCallName.lastIndexOf('/')); - managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); + context.managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); if (node.generator is! StringGeneratorAdapter) { var nameWithCubit = '${generalStateName.pascalCase}Cubit'; var nameWithState = '${generalStateName.pascalCase}State'; @@ -114,7 +115,7 @@ class BLoCMiddleware extends StateManagementMiddleware { var isFirst = true; states.forEach((element) { - element.currentContext.tree.data = node.managerData; + // element.currentContext.tree.data = node.managerData; // Creating copy of template to generate State var templateCopy = element.generator.templateStrategy; @@ -123,7 +124,7 @@ class BLoCMiddleware extends StateManagementMiddleware { isFirst: isFirst, abstractClassName: parentState, ); - stateBuffer.write(generationManager.generate(element)); + stateBuffer.write(generationManager.generate(element, context)); element.generator.templateStrategy = templateCopy; @@ -135,7 +136,7 @@ class BLoCMiddleware extends StateManagementMiddleware { /// modified the [UUID] to prevent adding import because the state is /// using `part of` syntax already when importing the bloc - 'STATE${node.currentContext.tree.UUID}', + 'STATE${context.tree.UUID}', '${generalName}_state', stateBuffer.toString(), symbolPath: blocDirectory,)); @@ -146,33 +147,33 @@ class BLoCMiddleware extends StateManagementMiddleware { /// modified the [UUID] to prevent adding import because the event is /// using `part of` syntax already when importing the bloc - '${node.currentContext.tree.UUID}', + '${context.tree.UUID}', '${generalName}_map', mapBuffer.toString(), symbolPath: blocDirectory)); // Generate node's states' view pages node.auxiliaryData?.stateGraph?.states?.forEach((state) { - fileStrategy.commandCreated(WriteSymbolCommand( - 'SYMBOL${state.variation.node.currentContext.tree.UUID}', + fileStrategy.commandCreated(WriteSymbolCommand('TODO', + // 'SYMBOL${state.variation.node.currentContext.tree.UUID}', state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node), + generationManager.generate(state.variation.node, context), relativePath: generalName, //Generate view files separately )); }); // Generate default node's view page fileStrategy.commandCreated(WriteSymbolCommand( - 'SYMBOL${node.currentContext.tree.UUID}', + 'SYMBOL${context.tree.UUID}', node.name.snakeCase, - generationManager.generate(node), + generationManager.generate(node, context), relativePath: generalName)); /// Creates cubit page - managerData.addImport(FlutterImport('meta.dart', 'meta')); - managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); + context.managerData.addImport(FlutterImport('meta.dart', 'meta')); + context.managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); fileStrategy.commandCreated(WriteSymbolCommand( - node.currentContext.tree.UUID, + context.tree.UUID, '${generalName}_cubit', _createBlocPage( parentState, diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 1f651470..bc809ade 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; @@ -43,13 +44,14 @@ class ProviderMiddleware extends StateManagementMiddleware { } @override - Future handleStatefulNode(PBIntermediateNode node) { + Future handleStatefulNode( + PBIntermediateNode node, PBContext context) { String watcherName; - var managerData = node.managerData; + var managerData = context.managerData; var fileStrategy = configuration.fileStructureStrategy as ProviderFileStructureStrategy; if (node is PBSharedInstanceIntermediateNode) { - node.currentContext.project.genProjectData + context.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); managerData.addImport(FlutterImport('provider.dart', 'provider')); watcherName = getVariableName(node.name.snakeCase + '_notifier'); @@ -99,19 +101,19 @@ class ProviderMiddleware extends StateManagementMiddleware { ..addImport(FlutterImport('material.dart', 'flutter'))); // Write model class for current node var code = MiddlewareUtils.generateModelChangeNotifier( - watcherName, modelGenerator, node); + watcherName, modelGenerator, node, context); [ /// This generated the `changeNotifier` that goes under the [fileStrategy.RELATIVE_MODEL_PATH] WriteSymbolCommand( - node.currentContext.tree.UUID, + context.tree.UUID, parentDirectory, code, symbolPath: fileStrategy.RELATIVE_MODEL_PATH, ), // Generate default node's view page - WriteSymbolCommand(node.currentContext.tree.UUID, node.name.snakeCase, - generationManager.generate(node), + WriteSymbolCommand(context.tree.UUID, node.name.snakeCase, + generationManager.generate(node, context), relativePath: parentDirectory), ].forEach(fileStrategy.commandCreated); @@ -122,9 +124,10 @@ class ProviderMiddleware extends StateManagementMiddleware { // Generate node's states' view pages node.auxiliaryData?.stateGraph?.states?.forEach((state) { fileStrategy.commandCreated(WriteSymbolCommand( - state.variation.node.currentContext.tree.UUID, + 'TODO', + // state.variation.node.currentContext.tree.UUID, state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node), + generationManager.generate(state.variation.node, context), relativePath: parentDirectory, )); }); diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 73a7cf18..050f256e 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/generation/generators/value_objects/generator_adap import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import '../../pb_flutter_generator.dart'; import '../../pb_generation_manager.dart'; @@ -44,14 +45,15 @@ class RiverpodMiddleware extends StateManagementMiddleware { } @override - Future handleStatefulNode(PBIntermediateNode node) { + Future handleStatefulNode( + PBIntermediateNode node, PBContext context) { String watcherName; - var managerData = node.managerData; + var managerData = context.managerData; var fileStrategy = configuration.fileStructureStrategy as RiverpodFileStructureStrategy; if (node is PBSharedInstanceIntermediateNode) { - node.currentContext.project.genProjectData + context.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); managerData.addImport( FlutterImport('flutter_riverpod.dart', 'flutter_riverpod')); @@ -59,7 +61,7 @@ class RiverpodMiddleware extends StateManagementMiddleware { var watcher = PBVariable(watcherName + '_provider', 'final ', true, 'ChangeNotifierProvider((ref) => ${ImportHelper.getName(node.functionCallName).pascalCase}())'); - if (node.currentContext.tree.rootNode.generator.templateStrategy + if (context.tree.rootNode.generator.templateStrategy is StatelessTemplateStrategy) { managerData.addGlobalVariable(watcher); } else { @@ -85,28 +87,29 @@ class RiverpodMiddleware extends StateManagementMiddleware { ..addImport(FlutterImport('material.dart', 'flutter'))); // Write model class for current node var code = MiddlewareUtils.generateModelChangeNotifier( - watcherName, modelGenerator, node); + watcherName, modelGenerator, node, context); [ /// This generated the `changeNotifier` that goes under the [fileStrategy.RELATIVE_MODEL_PATH] WriteSymbolCommand( - node.currentContext.tree.UUID, + context.tree.UUID, parentDirectory, code, symbolPath: fileStrategy.RELATIVE_MODEL_PATH, ), // Generate default node's view page - WriteSymbolCommand(node.currentContext.tree.UUID, node.name.snakeCase, - generationManager.generate(node), + WriteSymbolCommand(context.tree.UUID, node.name.snakeCase, + generationManager.generate(node, context), relativePath: parentDirectory), ].forEach(fileStrategy.commandCreated); // Generate node's states' view pages node.auxiliaryData?.stateGraph?.states?.forEach((state) { fileStrategy.commandCreated(WriteSymbolCommand( - state.variation.node.currentContext.tree.UUID, + 'TODO', + // state.variation.node.currentContext.tree.UUID, state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node), + generationManager.generate(state.variation.node, context), relativePath: parentDirectory, )); }); diff --git a/lib/generation/generators/middleware/state_management/state_management_middleware.dart b/lib/generation/generators/middleware/state_management/state_management_middleware.dart index 1400341b..fe82e025 100644 --- a/lib/generation/generators/middleware/state_management/state_management_middleware.dart +++ b/lib/generation/generators/middleware/state_management/state_management_middleware.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; @@ -29,20 +30,22 @@ abstract class StateManagementMiddleware extends Middleware { /// in which case the tree will return `null`; no other [Middleware] will be applied to the [tree], /// making the final result `null`. @override - Future applyMiddleware(PBIntermediateTree tree) { + Future applyMiddleware( + PBIntermediateTree tree, PBContext context) { return Future.wait(tree.map((node) { if (containsState(node) || containsMasterState(node)) { - return handleStatefulNode(node); + return handleStatefulNode(node, context); } return Future.value(node); })).then((nodes) { tree.rootNode = nodes.first; - return handleTree(tree.rootNode == null ? null : tree); + return handleTree(tree.rootNode == null ? null : tree, context); }); } /// Handles the nodes that are stateful(either [containsState] or [containsMasterState]). - Future handleStatefulNode(PBIntermediateNode node); + Future handleStatefulNode( + PBIntermediateNode node, PBContext context); /// Checks whether the master of the [PBSharedInstanceIntermediateNode] (if the [node] /// is a symbol) [containsState]. diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 8a5b51ab..1ddf5e55 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; import 'package:path/path.dart' as p; @@ -28,7 +29,7 @@ class StatefulMiddleware extends StateManagementMiddleware { } @override - Future handleStatefulNode(PBIntermediateNode node) { + Future handleStatefulNode(PBIntermediateNode node, PBContext context) { var fileStrategy = configuration.fileStructureStrategy; if (node is PBSharedInstanceIntermediateNode) { @@ -37,16 +38,17 @@ class StatefulMiddleware extends StateManagementMiddleware { } fileStrategy.commandCreated(WriteSymbolCommand( - node.currentContext.tree.UUID, + context.tree.UUID, node.name.snakeCase, - generationManager.generate(node))); + generationManager.generate(node, context))); node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - state.variation.node.currentContext.tree.data = node.managerData; + // state.variation.node.currentContext.tree.data = node.managerData; fileStrategy.commandCreated(WriteSymbolCommand( - state.variation.node.currentContext.tree.UUID, + 'TODO', + // state.variation.node.currentContext.tree.UUID, state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node))); + generationManager.generate(state.variation.node, context))); }); return Future.value(null); } diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 356fc195..afd4c569 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -1,3 +1,4 @@ + import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -9,6 +10,7 @@ class MiddlewareUtils { String defaultStateName, PBGenerationManager manager, PBIntermediateNode node, + PBContext context ) { var overrideVars = ''; // Variables outside of initializer var overrideAttr = ''; // Attributes that will be part of initializer @@ -28,7 +30,7 @@ class MiddlewareUtils { stateBuffer.write(MiddlewareUtils.generateVariable(node)); } node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - state.variation.node.currentContext.tree.data = node.managerData; + context.tree.data = context.managerData; var variationNode = state.variation.node; if (variationNode is PBSharedMasterNode && @@ -67,10 +69,11 @@ class MiddlewareUtils { String defaultStateName, PBGenerationManager manager, PBIntermediateNode node, + PBContext context ) { // Pass down manager data to states node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - state.variation.node.currentContext.tree.data = node.managerData; + // context.tree.data = node.managerData; }); return ''' ${manager.generateImports()} @@ -100,8 +103,8 @@ class MiddlewareUtils { '$type ${node.name.camelCase};'; static String generateVariableBody(PBIntermediateNode node) { - node.currentContext.sizingContext = SizingValueContext.PointValue; - return (node?.generator?.generate(node ?? '', node.currentContext) ?? ''); + // node.currentContext.sizingContext = SizingValueContext.PointValue; + // return (node?.generator?.generate(node ?? '', node.currentContext) ?? ''); } static String wrapOnLayout(String className) { diff --git a/lib/generation/generators/pb_flutter_generator.dart b/lib/generation/generators/pb_flutter_generator.dart index 53769634..b881903f 100644 --- a/lib/generation/generators/pb_flutter_generator.dart +++ b/lib/generation/generators/pb_flutter_generator.dart @@ -102,6 +102,7 @@ class PBFlutterGenerator extends PBGenerationManager { @override String generate( PBIntermediateNode rootNode, + PBContext context, ) { if (rootNode == null) { return null; @@ -110,12 +111,12 @@ class PBFlutterGenerator extends PBGenerationManager { if (rootNode.generator == null) { log.error('Generator not registered for $rootNode'); } - rootNode.currentContext.sizingContext = SizingValueContext.PointValue; + context.sizingContext = SizingValueContext.PointValue; return rootNode.generator?.templateStrategy - ?.generateTemplate(rootNode, this, rootNode.currentContext) ?? + ?.generateTemplate(rootNode, this, context) ?? ///if there is no [TemplateStrategy] we are going to use `DEFAULT_STRATEGY` DEFAULT_STRATEGY.generateTemplate( - rootNode, this, rootNode.currentContext); + rootNode, this, context); } } diff --git a/lib/generation/generators/pb_generation_manager.dart b/lib/generation/generators/pb_generation_manager.dart index cfab3237..6be0c758 100644 --- a/lib/generation/generators/pb_generation_manager.dart +++ b/lib/generation/generators/pb_generation_manager.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -24,7 +25,7 @@ abstract class PBGenerationManager { _data = data; } - String generate(PBIntermediateNode rootNode); + String generate(PBIntermediateNode rootNode, PBContext context); Set getPaths(String uuid) => PBGenCache().getPaths(uuid); diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index 52245252..6d16ea7c 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -10,12 +10,10 @@ abstract class PBEgg extends PBVisualIntermediateNode { PBEgg( String UUID, Rectangle frame, - PBContext currentContext, String name, ) : super( UUID, frame, - currentContext, name, ); diff --git a/lib/generation/generators/symbols/pb_mastersym_gen.dart b/lib/generation/generators/symbols/pb_mastersym_gen.dart index 0a1c2e7a..933f5b4c 100644 --- a/lib/generation/generators/symbols/pb_mastersym_gen.dart +++ b/lib/generation/generators/symbols/pb_mastersym_gen.dart @@ -10,22 +10,22 @@ class PBMasterSymbolGenerator extends PBGenerator { var log = Logger('Symbol Master Generator'); @override - String generate(PBIntermediateNode source, PBContext generatorContext) { - generatorContext.sizingContext = SizingValueContext.LayoutBuilderValue; + String generate(PBIntermediateNode source, PBContext context) { + context.sizingContext = SizingValueContext.LayoutBuilderValue; var buffer = StringBuffer(); if (source is PBSharedMasterNode) { if (source.child == null) { return ''; } // override styles if need be. - generatorContext.masterNode = source; + context.masterNode = source; - source.child.currentContext = source.currentContext; + // source.child.currentContext = source.currentContext; // see if widget itself is overridden, need to pass var generatedWidget = - source.child.generator.generate(source.child, generatorContext); + source.child.generator.generate(source.child, context); - generatorContext.masterNode = null; + context.masterNode = null; if (generatedWidget == null || generatedWidget.isEmpty) { return ''; } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 018fed5c..a4f30eaa 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/flutter_project_builder/file_writer_observer.dart'; @@ -108,11 +109,11 @@ abstract class FileStructureStrategy implements CommandInvoker { _screenDirectoryPath = p.join(GENERATED_PROJECT_PATH, RELATIVE_SCREEN_PATH); _viewDirectoryPath = p.join(GENERATED_PROJECT_PATH, RELATIVE_VIEW_PATH); - _pbProject.forest.forEach((dir) { - if (dir.rootNode != null) { - addImportsInfo(dir); - } - }); + // _pbProject.forest.forEach((dir) { + // if (dir.rootNode != null) { + // addImportsInfo(dir, context); + // } + // }); Directory(_screenDirectoryPath).createSync(recursive: true); Directory(_viewDirectoryPath).createSync(recursive: true); isSetUp = true; @@ -120,7 +121,7 @@ abstract class FileStructureStrategy implements CommandInvoker { } ///Add the import information to correctly generate them in the corresponding files. - void addImportsInfo(PBIntermediateTree tree) { + void addImportsInfo(PBIntermediateTree tree, PBContext context) { var poLinker = PBPlatformOrientationLinkerService(); // Add to cache if node is scaffold or symbol master var node = tree.rootNode; @@ -132,7 +133,7 @@ abstract class FileStructureStrategy implements CommandInvoker { : p.join(_screenDirectoryPath, tree.name.snakeCase, name); if (poLinker.screenHasMultiplePlatforms(tree.rootNode.name)) { path = p.join(_screenDirectoryPath, name, - poLinker.stripPlatform(tree.rootNode.managerData.platform), name); + poLinker.stripPlatform(context.managerData.platform), name); } PBGenCache().setPathToCache(uuid, path); diff --git a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart index 0d51a202..9799243c 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:path/path.dart' as p; diff --git a/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart index 01490004..2efae3be 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 6c14146d..77d49d71 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -21,6 +21,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; @@ -75,8 +76,9 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } ///This is going to modify the [PBIntermediateNode] in order to affect the structural patterns or file structure produced. - Future applyMiddleware(PBIntermediateTree tree) => - _head.applyMiddleware(tree); + Future applyMiddleware( + PBIntermediateTree tree, PBContext context) => + _head.applyMiddleware(tree, context); /// It is generating the [List] of [trees] by passing them through the link list /// of [Middleware]. @@ -87,27 +89,28 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { /// Finally, if the [PBIntermediateTree.isHomeScreen], it will modify the main file to /// reflect that information. At the end, the [Middleware] should be executing [FileStructureCommands] /// that generate the code for each tree in the [trees]. - Future generateTrees( - List trees, PBProject project) async { - for (var tree in trees) { - tree.rootNode.currentContext.generationManager = generationManager; - generationManager.data = tree.data; - tree.data.addImport(FlutterImport('material.dart', 'flutter')); - - // Relative path to the file to create - var relPath = p.join(tree.name.snakeCase, tree.identifier); - - // Change relative path if current tree is part of multi-platform setup - if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { - var platformFolder = - poLinker.stripPlatform(tree.rootNode.managerData.platform); - relPath = p.join(tree.identifier, platformFolder, tree.identifier); - } - if (tree.isHomeScreen()) { - await _setMainScreen(tree, relPath, MainInfo().projectName); - } - await applyMiddleware(tree); + Future generateTree(PBIntermediateTree tree, PBProject project, + PBContext context, bool lockData) async { + fileStructureStrategy.dryRunMode = lockData; + tree.lockData = lockData; + fileStructureStrategy.addImportsInfo(tree, context); + + context.generationManager = generationManager; + generationManager.data = tree.data; + tree.data.addImport(FlutterImport('material.dart', 'flutter')); + + // Relative path to the file to create + var relPath = p.join(tree.name.snakeCase, tree.identifier); + + // Change relative path if current tree is part of multi-platform setup + if (poLinker.screenHasMultiplePlatforms(tree.identifier)) { + var platformFolder = poLinker.stripPlatform(context.managerData.platform); + relPath = p.join(tree.identifier, platformFolder, tree.identifier); + } + if (tree.isHomeScreen()) { + await _setMainScreen(tree, relPath, MainInfo().projectName); } + await applyMiddleware(tree, context); } ///Generates the [PBIntermediateTree]s within the [pb_project] @@ -120,21 +123,21 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ///gather all the necessary information await setUpConfiguration(pb_project); - fileStructureStrategy.dryRunMode = true; + // fileStructureStrategy.dryRunMode = true; fileStructureStrategy.addFileObserver(_importProcessor); - pb_project.fileStructureStrategy = fileStructureStrategy; + // pb_project.fileStructureStrategy = fileStructureStrategy; - pb_project.lockData = true; - commandQueue.forEach(fileStructureStrategy.commandCreated); - await generateTrees(pb_project.forest, pb_project); - pb_project.lockData = false; + // pb_project.lockData = true; + // commandQueue.forEach(fileStructureStrategy.commandCreated); + // await generateTrees(pb_project.forest, pb_project, context); + // pb_project.lockData = false; ///After the dry run is complete, then we are able to create the actual files. - fileStructureStrategy.dryRunMode = false; + // fileStructureStrategy.dryRunMode = false; - commandQueue.forEach(fileStructureStrategy.commandCreated); + // commandQueue.forEach(fileStructureStrategy.commandCreated); commandQueue.clear(); - await generateTrees(pb_project.forest, pb_project); + // await generateTrees(pb_project.forest, pb_project, context); await _commitDependencies(processInfo.genProjectPath); } @@ -151,7 +154,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } ///Configure the required classes for the [PBGenerationConfiguration] - Future setUpConfiguration(PBProject pbProject) async { + Future setUpConfiguration( + PBProject pbProject) async { fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); commandObservers.add(fileStructureStrategy); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index 1867ef64..dcf9a2ca 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_screen_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:recase/recase.dart'; @@ -73,20 +74,20 @@ mixin PBPlatformOrientationGeneration { return result; } - void getPlatformOrientationName(PBIntermediateNode node) { + void getPlatformOrientationName(PBIntermediateNode node, PBContext context) { var map = PBPlatformOrientationLinkerService() - .getPlatformOrientationData(node.currentContext.tree.identifier); + .getPlatformOrientationData(context.tree.identifier); if (map.length > 1) { var platform = PBPlatformOrientationLinkerService() - .stripPlatform(node.currentContext.tree.data.platform); + .stripPlatform(context.tree.data.platform); if (!node.name.contains('_$platform')) { node.name += '_$platform'; } } - if (map[node.currentContext.tree.data.platform].length > 1) { + if (map[context.tree.data.platform].length > 1) { var orientation = PBPlatformOrientationLinkerService() - .stripOrientation(node.currentContext.tree.data.orientation); + .stripOrientation(context.tree.data.orientation); if (!node.name.contains('_$orientation')) { node.name += '_$orientation'; } diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index 3b199e4e..c7009858 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -10,10 +10,10 @@ class BLoCStateTemplateStrategy extends TemplateStrategy { BLoCStateTemplateStrategy({this.isFirst, this.abstractClassName}); @override String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, - PBContext generatorContext, + PBContext context, {args}) { - node.managerData.hasParams = true; - node.managerData.hasParams = false; + context.managerData.hasParams = true; + context.managerData.hasParams = false; return ''' ${isFirst ? _getHeader(manager) : ''} diff --git a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart index 8a2925d9..bee6edb8 100644 --- a/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart @@ -8,12 +8,12 @@ import 'package:recase/recase.dart'; class StatelessTemplateStrategy extends TemplateStrategy { @override String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, - PBContext generatorContext, + PBContext context, {args}) { var widgetName = node.name; - node.managerData.hasParams = true; - var returnStatement = node.generator.generate(node, generatorContext); - node.managerData.hasParams = false; + context.managerData.hasParams = true; + var returnStatement = node.generator.generate(node, context); + context.managerData.hasParams = false; var overrides = ''; var overrideVars = ''; diff --git a/lib/generation/generators/visual-widgets/pb_align_gen.dart b/lib/generation/generators/visual-widgets/pb_align_gen.dart index 16e9f25f..600a8327 100644 --- a/lib/generation/generators/visual-widgets/pb_align_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_align_gen.dart @@ -10,7 +10,7 @@ class PBAlignGenerator extends PBGenerator { PBAlignGenerator() : super(); @override - String generate(PBIntermediateNode source, PBContext generatorContext) { + String generate(PBIntermediateNode source, PBContext context) { if (source is InjectedAlign) { var buffer = StringBuffer(); buffer.write('Align('); @@ -19,9 +19,9 @@ class PBAlignGenerator extends PBGenerator { 'alignment: Alignment(${source.alignX.toStringAsFixed(2)}, ${source.alignY.toStringAsFixed(2)}),'); try { - source.child.currentContext = source.currentContext; + // source.child.currentContext = source.currentContext; buffer.write( - 'child: ${source.child.generator.generate(source.child, generatorContext)},'); + 'child: ${source.child.generator.generate(source.child, context)},'); } catch (e, stackTrace) { MainInfo().sentry.captureException( exception: e, diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index f5843977..ac72643d 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -12,16 +12,16 @@ class PBContainerGenerator extends PBGenerator { PBContainerGenerator() : super(); @override - String generate(PBIntermediateNode source, PBContext generatorContext) { + String generate(PBIntermediateNode source, PBContext context) { var buffer = StringBuffer(); buffer.write('Container('); - buffer.write(PBSizeHelper().generate(source, generatorContext)); + buffer.write(PBSizeHelper().generate(source, context)); if (source.auxiliaryData.borderInfo != null) { - buffer.write(PBBoxDecorationHelper().generate(source, generatorContext)); + buffer.write(PBBoxDecorationHelper().generate(source, context)); } else { - buffer.write(PBColorGenHelper().generate(source, generatorContext)); + buffer.write(PBColorGenHelper().generate(source, context)); } // if (source.auxiliaryData.alignment != null) { @@ -30,13 +30,10 @@ class PBContainerGenerator extends PBGenerator { // } if (source.child != null) { - source.child.topLeftCorner = - Point(source.topLeftCorner.x, source.topLeftCorner.y); - source.child.bottomRightCorner = - Point(source.bottomRightCorner.x, source.bottomRightCorner.y); - source.child.currentContext = source.currentContext; + source.child.frame = source.frame; + // source.child.currentContext = source.currentContext; var statement = source.child != null - ? 'child: ${source.child.generator.generate(source.child, generatorContext)}' + ? 'child: ${source.child.generator.generate(source.child, context)}' : ''; buffer.write(statement); } diff --git a/lib/generation/generators/visual-widgets/pb_flexible_gen.dart b/lib/generation/generators/visual-widgets/pb_flexible_gen.dart index 5e7b7f75..50ed38b1 100644 --- a/lib/generation/generators/visual-widgets/pb_flexible_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_flexible_gen.dart @@ -9,15 +9,15 @@ class PBFlexibleGenerator extends PBGenerator { PBFlexibleGenerator() : super(); @override - String generate(PBIntermediateNode source, PBContext generatorContext) { + String generate(PBIntermediateNode source, PBContext context) { if (source is Flexible) { var buffer = StringBuffer(); buffer.write('Flexible('); buffer.write('flex: ${source.flex},'); try { - source.child.currentContext = source.currentContext; + // source.child.currentContext = source.currentContext; buffer.write( - 'child: ${source.child.generator.generate(source.child, generatorContext)},'); + 'child: ${source.child.generator.generate(source.child, context)},'); } catch (e) { log.error(e.toString()); } diff --git a/lib/generation/generators/visual-widgets/pb_padding_gen.dart b/lib/generation/generators/visual-widgets/pb_padding_gen.dart index 511c5bc0..e51ca69e 100644 --- a/lib/generation/generators/visual-widgets/pb_padding_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_padding_gen.dart @@ -32,10 +32,10 @@ class PBPaddingGen extends PBGenerator { } @override - String generate(PBIntermediateNode source, PBContext generatorContext) { - if (generatorContext.sizingContext == SizingValueContext.AppBarChild) { - source.child.currentContext = source.currentContext; - return source.child.generator.generate(source.child, generatorContext); + String generate(PBIntermediateNode source, PBContext context) { + if (context.sizingContext == SizingValueContext.AppBarChild) { + // source.child.currentContext = source.currentContext; + return source.child.generator.generate(source.child, context); } if (!(source is Padding)) { return ''; @@ -76,9 +76,9 @@ class PBPaddingGen extends PBGenerator { buffer.write('),'); if (source.child != null) { - source.child.currentContext = source.currentContext; + // source.child.currentContext = source.currentContext; buffer.write( - 'child: ${source.child.generator.generate(source.child, generatorContext)}'); + 'child: ${source.child.generator.generate(source.child, context)}'); } buffer.write(')'); diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 8d7695eb..094d0c12 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -17,15 +17,15 @@ class PBPositionedGenerator extends PBGenerator { PBPositionedGenerator({this.overrideChildDim = false}) : super(); @override - String generate(PBIntermediateNode source, PBContext generatorContext) { + String generate(PBIntermediateNode source, PBContext context) { if (source is InjectedPositioned) { var buffer = StringBuffer('Positioned('); - var boilerplate = _getBoilerplate(generatorContext.sizingContext); + var boilerplate = _getBoilerplate(context.sizingContext); var xAxisBoilerplate = boilerplate.item1; var yAxisBoilerplate = boilerplate.item2; - if (generatorContext.tree.first.name == 'ArtboardTRpinnoscale') { + if (context.tree.first.name == 'ArtboardTRpinnoscale') { print('asdf'); } @@ -45,10 +45,10 @@ class PBPositionedGenerator extends PBGenerator { var positionalAtt = _getPositionalAtt(valueHolder, source.constraints); - if (!(generatorContext.sizingContext == SizingValueContext.PointValue)) { + if (!(context.sizingContext == SizingValueContext.PointValue)) { /// [SizingValueContext.PointValue] is the only value in which dont change based on another scale/sizing - var ratio = source.currentContext.getRatioPercentage; + var ratio = context.getRatioPercentage; for (var attribute in positionalAtt) { if (!attribute.remainPointValue) { attribute.value = @@ -79,9 +79,9 @@ class PBPositionedGenerator extends PBGenerator { // 'right: ${_normalizeValue(xAxisBoilerplate, valueHolder.right)}, bottom: ${_normalizeValue(yAxisBoilerplate, valueHolder.bottom)},'); // } - source.child.currentContext = source.currentContext; + // source.child.currentContext = source.currentContext; buffer.write( - 'child: ${source.child.generator.generate(source.child, generatorContext)},'); + 'child: ${source.child.generator.generate(source.child, context)},'); } catch (e) { logger.error(e.toString()); MainInfo().captureException( diff --git a/lib/generation/generators/visual-widgets/pb_text_gen.dart b/lib/generation/generators/visual-widgets/pb_text_gen.dart index cffbfced..207f822f 100644 --- a/lib/generation/generators/visual-widgets/pb_text_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_text_gen.dart @@ -10,12 +10,12 @@ class PBTextGen extends PBGenerator { PBTextGen() : super(); @override - String generate(PBIntermediateNode source, PBContext generatorContext) { + String generate(PBIntermediateNode source, PBContext context) { if (source is InheritedText) { - source.currentContext.project.genProjectData + context.project.genProjectData .addDependencies('auto_size_text', '^2.1.0'); - source.managerData + context.managerData .addImport(FlutterImport('auto_size_text.dart', 'auto_size_text')); var buffer = StringBuffer(); buffer.write('AutoSizeText(\n'); @@ -56,7 +56,7 @@ class PBTextGen extends PBGenerator { buffer.write('letterSpacing: ${source.letterSpacing},\n'); } if (source.auxiliaryData.color != null) { - buffer.write(PBColorGenHelper().generate(source, generatorContext)); + buffer.write(PBColorGenHelper().generate(source, context)); } buffer.write('),'); diff --git a/lib/generation/prototyping/pb_dest_holder.dart b/lib/generation/prototyping/pb_dest_holder.dart index f80867ec..c4c7a33e 100644 --- a/lib/generation/prototyping/pb_dest_holder.dart +++ b/lib/generation/prototyping/pb_dest_holder.dart @@ -8,12 +8,10 @@ import 'dart:math'; class PBDestHolder extends PBIntermediateNode { PrototypeNode pNode; - @override - ChildrenStrategy childrenStrategy = OneChildStrategy('child'); - PBDestHolder( - String UUID, Rectangle frame, this.pNode, PBContext currentContext) - : super(UUID, frame, '', currentContext: currentContext) { + String UUID, Rectangle frame, this.pNode) + : super(UUID, frame, '') { generator = PBPrototypeGenerator(pNode); + childrenStrategy = OneChildStrategy('child'); } } diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index e22a7786..3a664ea0 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -8,6 +8,8 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:path/path.dart'; /// This class keeps track of the [PrototypeNode]s that do not have necessary /// properties from their destination [PBIntermediateNode] and populates them @@ -35,27 +37,29 @@ class PBPrototypeAggregationService { /// Iterates through `_unregNodes` to find whether any [PBPrototypeNode]'s /// `destinationUUID` matches the `node` UUID. If there is a match, populate /// the [PrototypeNode]. - Future analyzeIntermediateNode(PBIntermediateNode node) async { + Future analyzeIntermediateNode( + PBIntermediateNode node, PBContext context) async { if (node is InheritedScaffold) { screens.add(node); ///check if any of the [IntermediateNode]s looking for a destination contains their destination. - iterateUnregisterNodes(node); + iterateUnregisterNodes(node, context); } else if (node is PrototypeEnable) { var page = _storage.getPageNodeById( (node as PrototypeEnable).prototypeNode.destinationUUID); if (page == null) { _unregNodes.add(node as PrototypeEnable); } else { - _addDependent(node, page); + _addDependent(node, page, context); } } _unregNodes.removeWhere( (pNode) => pNode.prototypeNode.destinationUUID == node.UUID); } - void _addDependent(PBIntermediateNode target, PBIntermediateNode dependent) { - target.currentContext.addDependent(dependent.currentContext.tree); + void _addDependent(PBIntermediateNode target, PBIntermediateNode dependent, + PBContext context) { + context.addDependent(context.tree); } /// Provide the `pNode` with the necessary attributes it needs from the `iNode` @@ -65,26 +69,37 @@ class PBPrototypeAggregationService { return iNode; } else if (iNode is PBInheritedIntermediate) { var destHolder = PBDestHolder( - iNode.UUID, - iNode.frame, - (iNode as PBInheritedIntermediate).prototypeNode, - iNode.currentContext); + iNode.UUID, + iNode.frame, + (iNode as PBInheritedIntermediate).prototypeNode, + ); destHolder.addChild(iNode); return destHolder; } else if (iNode is PBLayoutIntermediateNode) { var destHolder = PBDestHolder( - iNode.UUID, iNode.frame, iNode.prototypeNode, iNode.currentContext); + iNode.UUID, + iNode.frame, + iNode.prototypeNode, + ); destHolder.addChild(iNode); return destHolder; } else if (iNode is InjectedContainer) { var destHolder = PBDestHolder( - iNode.UUID, iNode.frame, iNode.prototypeNode, iNode.currentContext); + iNode.UUID, + iNode.frame, + iNode.prototypeNode, + ); destHolder.addChild(iNode); return destHolder; } else if (iNode is Tab) { var destHolder = PBDestHolder( - iNode.UUID, iNode.frame, iNode.prototypeNode, iNode.currentContext); - destHolder.addChild(iNode.child); + iNode.UUID, + iNode.frame, + iNode.prototypeNode, + ); + iNode.children.forEach((element) { + destHolder.addChild(element); + }); return destHolder; } else { return iNode; @@ -95,19 +110,19 @@ class PBPrototypeAggregationService { // This temporal solution solves the issue for topological sorting // when two screens link each other, but one comes first // and does not get linked to the proper button on the screen - Future linkDanglingPrototypeNodes() async { + Future linkDanglingPrototypeNodes(PBContext context) async { if (_unregNodes.isNotEmpty) { for (var screen in screens) { - iterateUnregisterNodes(screen); + iterateUnregisterNodes(screen, context); } } } - void iterateUnregisterNodes(PBIntermediateNode node) { + void iterateUnregisterNodes(PBIntermediateNode node, PBContext context) { for (var _pNode in _unregNodes) { if (_pNode.prototypeNode.destinationUUID == node.UUID) { _pNode.prototypeNode.destinationName = node.name; - _addDependent(_pNode as PBIntermediateNode, node); + _addDependent(_pNode as PBIntermediateNode, node, context); } } } diff --git a/lib/generation/prototyping/pb_prototype_gen.dart b/lib/generation/prototyping/pb_prototype_gen.dart index 0cd7adb6..76228a71 100644 --- a/lib/generation/prototyping/pb_prototype_gen.dart +++ b/lib/generation/prototyping/pb_prototype_gen.dart @@ -23,10 +23,11 @@ class PBPrototypeGenerator extends PBGenerator { MaterialPageRoute(builder: (context) => $name()), ); }, - child: ${source.child.generator.generate(source.child, generatorContext)}, + child: ${source.children.first.generator.generate(source.children.first, generatorContext)}, )'''; } else { - return source.child.generator.generate(source.child, generatorContext); + return source.children.first.generator + .generate(source.children.first, generatorContext); } } } diff --git a/lib/generation/prototyping/pb_prototype_linker_service.dart b/lib/generation/prototyping/pb_prototype_linker_service.dart index f549017f..f03703f4 100644 --- a/lib/generation/prototyping/pb_prototype_linker_service.dart +++ b/lib/generation/prototyping/pb_prototype_linker_service.dart @@ -3,6 +3,8 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/services/intermediate_node_searcher_service.dart'; class PBPrototypeLinkerService { @@ -15,40 +17,29 @@ class PBPrototypeLinkerService { } Future linkPrototypeNodes( - PBIntermediateNode rootNode) async { + PBIntermediateTree tree, PBContext context) async { + var rootNode = tree.rootNode; if (rootNode == null) { return rootNode; } - - var stack = []; - stack.add(rootNode); - - while (stack.isNotEmpty) { - var currentNode = stack.removeLast(); - if (currentNode == null) { - continue; - } - currentNode.attributes.forEach((attribute) { - attribute.attributeNodes.forEach(stack.add); - }); - if (currentNode is InheritedScaffold) { - await _prototypeStorage.addPageNode(currentNode); - } else if (currentNode is PrototypeEnable) { - if ((currentNode as PrototypeEnable).prototypeNode?.destinationUUID != - null && - (currentNode as PrototypeEnable) - .prototypeNode - .destinationUUID - .isNotEmpty) { - addAndPopulatePrototypeNode(currentNode, rootNode); + for (var element in tree) { + if (element is InheritedScaffold) { + if (element is InheritedScaffold) { + await _prototypeStorage.addPageNode(element, context); + } else if (element is PrototypeEnable) { + if (((element)).prototypeNode?.destinationUUID != null && + (element).prototypeNode.destinationUUID.isNotEmpty) { + addAndPopulatePrototypeNode(element, rootNode, context); + } } } } return rootNode; } - void addAndPopulatePrototypeNode(var currentNode, var rootNode) async { - await _prototypeStorage.addPrototypeInstance(currentNode); + void addAndPopulatePrototypeNode( + var currentNode, var rootNode, PBContext context) async { + await _prototypeStorage.addPrototypeInstance(currentNode, context); currentNode = _aggregationService.populatePrototypeNode(currentNode) ?? currentNode; PBIntermediateNodeSearcherService.replaceNodeInTree( diff --git a/lib/generation/prototyping/pb_prototype_storage.dart b/lib/generation/prototyping/pb_prototype_storage.dart index 021596f9..4c610f03 100644 --- a/lib/generation/prototyping/pb_prototype_storage.dart +++ b/lib/generation/prototyping/pb_prototype_storage.dart @@ -1,6 +1,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_aggregation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBPrototypeStorage { static final PBPrototypeStorage _singleInstance = @@ -24,22 +25,25 @@ class PBPrototypeStorage { Iterable get prototypeIDs => _pbPrototypeInstanceNodes.keys; - Future addPrototypeInstance(PBIntermediateNode prototypeNode) async { + Future addPrototypeInstance( + PBIntermediateNode prototypeNode, PBContext context) async { if (_pbPrototypeInstanceNodes.containsKey(prototypeNode.UUID)) { return false; } await PBPrototypeAggregationService() - .analyzeIntermediateNode(prototypeNode); + .analyzeIntermediateNode(prototypeNode, context); _pbPrototypeInstanceNodes['${prototypeNode.UUID}'] = prototypeNode; return true; } - Future addPageNode(PBIntermediateNode pageNode) async { + Future addPageNode( + PBIntermediateNode pageNode, PBContext context) async { if (_pbPages.containsKey(pageNode.UUID)) { return false; } - await PBPrototypeAggregationService().analyzeIntermediateNode(pageNode); + await PBPrototypeAggregationService() + .analyzeIntermediateNode(pageNode, context); _pbPages['${pageNode.UUID}'] = pageNode; return true; } diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index 97ab6ee9..d02d2826 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -15,18 +15,18 @@ class Flexible extends PBVisualIntermediateNode { Flexible( String UUID, Rectangle frame, { - PBContext currentContext, child, this.flex, }) : super( UUID, frame, - currentContext, '', ) { generator = PBFlexibleGenerator(); childrenStrategy = OneChildStrategy('child'); - this.child = child; + if(child != null){ + addChild(child); + } } @override diff --git a/lib/interpret_and_optimize/entities/alignments/injected_align.dart b/lib/interpret_and_optimize/entities/alignments/injected_align.dart index 306b7781..1fa972ec 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_align.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_align.dart @@ -13,44 +13,43 @@ class InjectedAlign extends PBVisualIntermediateNode double alignX; double alignY; - InjectedAlign( - String UUID, Rectangle frame, PBContext currentContext, String name) - : super(UUID, frame, currentContext, name) { + InjectedAlign(String UUID, Rectangle frame, String name) + : super(UUID, frame, name) { generator = PBAlignGenerator(); childrenStrategy = TempChildrenStrategy('child'); } @override void alignChild() { - var maxX = (topLeftCorner.x - bottomRightCorner.x).abs() - - (child.bottomRightCorner.x - child.topLeftCorner.x).abs(); - var parentCenterX = (topLeftCorner.x + bottomRightCorner.x) / 2; - var childCenterX = (child.topLeftCorner.x + child.bottomRightCorner.x) / 2; - var alignmentX = 0.0; - - if (maxX != 0.0) { - alignmentX = ((childCenterX - parentCenterX) / maxX) * 2; - } - - var parentCenterY = (topLeftCorner.y + bottomRightCorner.y) / 2; - var maxY = (topLeftCorner.y - bottomRightCorner.y).abs() - - (child.bottomRightCorner.y - child.topLeftCorner.y).abs(); - var childCenterY = (child.topLeftCorner.y + child.bottomRightCorner.y) / 2; - var alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; - - if (maxY != 0.0) { - alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; - } - - if (alignmentX.isNaN) { - alignmentX = 0; - } - if (alignmentY.isNaN) { - alignmentY = 0; - } - - alignX = alignmentX.toDouble(); - alignY = alignmentY.toDouble(); + // var maxX = (frame.topLeft.x - frame.bottomRight.x).abs() - + // (child.frame.bottomRight.x - child.frame.topLeft.x).abs(); + // var parentCenterX = (frame.topLeft.x + frame.bottomRight.x) / 2; + // var childCenterX = (child.frame.topLeft.x + child.frame.bottomRight.x) / 2; + // var alignmentX = 0.0; + + // if (maxX != 0.0) { + // alignmentX = ((childCenterX - parentCenterX) / maxX) * 2; + // } + + // var parentCenterY = (frame.topLeft.y + frame.bottomRight.y) / 2; + // var maxY = (frame.topLeft.y - frame.bottomRight.y).abs() - + // (child.frame.bottomRight.y - child.frame.topLeft.y).abs(); + // var childCenterY = (child.frame.topLeft.y + child.frame.bottomRight.y) / 2; + // var alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; + + // if (maxY != 0.0) { + // alignmentY = ((childCenterY - parentCenterY) / maxY) * 2; + // } + + // if (alignmentX.isNaN) { + // alignmentX = 0; + // } + // if (alignmentY.isNaN) { + // alignmentY = 0; + // } + + // alignX = alignmentX.toDouble(); + // alignY = alignmentY.toDouble(); } @override diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index 273db7b5..c0454898 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -17,10 +17,8 @@ class InjectedPositioned extends PBIntermediateNode String UUID, Rectangle frame, { this.valueHolder, - PBContext currentContext, PBIntermediateConstraints constraints, - }) : super(UUID, frame, '', - currentContext: currentContext, constraints: constraints) { + }) : super(UUID, frame, '', constraints: constraints) { generator = PBPositionedGenerator(overrideChildDim: true); } diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index 0922d51e..89351fbd 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -13,10 +13,7 @@ class Padding extends PBVisualIntermediateNode { Map padding; PBIntermediateConstraints childToParentConstraints; - - @override - ChildrenStrategy childrenStrategy = OneChildStrategy('child'); - + Padding( String UUID, Rectangle frame, @@ -25,33 +22,19 @@ class Padding extends PBVisualIntermediateNode { this.right = 0, this.top = 0, this.bottom = 0, - PBContext currentContext, }) : super( UUID, frame, - currentContext, '', ) { generator = PBPaddingGen(); + childrenStrategy = OneChildStrategy('child'); } @override - void addChild(node) { - assert(child == null, 'Padding cannot accept multiple children.'); - child = node; - - // Calculate art board with - screenWidth = child.currentContext == null - ? (child.bottomRightCorner.x - child.topLeftCorner.x).abs() - : (child.currentContext.screenBottomRightCorner.x - - child.currentContext.screenTopLeftCorner.x) - .abs(); - // Calculate art board height - screenHeight = child.currentContext == null - ? (child.bottomRightCorner.y - child.topLeftCorner.y).abs() - : (child.currentContext.screenBottomRightCorner.y - - child.currentContext.screenTopLeftCorner.y) - .abs(); + void handleChildren(PBContext context) { + screenHeight = context.screenFrame.height; + screenWidth = context.screenFrame.width; /// Calculating the percentage of the padding in relation to the [screenHeight] and the [screenWidth]. /// FIXME: creating a lifecyle between the [PBGenerator] and the [PBIntermediateNode] where it provides a callback that @@ -74,8 +57,28 @@ class Padding extends PBVisualIntermediateNode { bottom = bottom / screenHeight; bottom = bottom < 0.01 ? 0.0 : bottom; } + super.handleChildren(context); } + // @override + // void addChild(PBIntermediateNode node) { + // assert(child == null, 'Padding cannot accept multiple children.'); + // child = node; + + // // Calculate art board with + // screenWidth = child.currentContext == null + // ? (child.frame.bottomRight.x - child.frame.topLeft.x).abs() + // : (child.currentContext.screenFrame.bottomRight.x - + // child.currentContext.screenFrame.topLeft.x) + // .abs(); + // // Calculate art board height + // screenHeight = child.currentContext == null + // ? (child.frame.bottomRight.y - child.frame.topLeft.y).abs() + // : (child.currentContext.screenFrame.bottomRight.y - + // child.currentContext.screenFrame.topLeft.y) + // .abs(); + // } + @override PBIntermediateNode fromJson(Map json) => null; } diff --git a/lib/interpret_and_optimize/entities/alignments/spacer.dart b/lib/interpret_and_optimize/entities/alignments/spacer.dart index 41309051..e0152bf3 100644 --- a/lib/interpret_and_optimize/entities/alignments/spacer.dart +++ b/lib/interpret_and_optimize/entities/alignments/spacer.dart @@ -10,17 +10,14 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class Spacer extends PBVisualIntermediateNode { int flex; - @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - Spacer(String UUID, Rectangle frame, {this.flex, PBContext currentContext}) : super( UUID, frame, - currentContext, '', ) { generator = PBSpacerGenerator(); + childrenStrategy = NoChildStrategy(); } @override diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index c8951e0c..9a0ac5b0 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -35,27 +35,15 @@ class InheritedBitmap extends PBVisualIntermediateNode @JsonKey() String type = 'image'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - @override @JsonKey(ignore: true) Map originalRef; - InheritedBitmap( - String UUID, - Rectangle frame, { - this.originalRef, - String name, - PBContext currentContext, - this.referenceImage, - this.prototypeNode, - this.size, - }) : super( + InheritedBitmap(String UUID, Rectangle frame, + {this.originalRef, String name, this.referenceImage, this.prototypeNode}) + : super( UUID, frame, - currentContext, name, ) { generator = PBBitmapGenerator(); @@ -67,11 +55,12 @@ class InheritedBitmap extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$InheritedBitmapFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) + // . .frame.topLeft = Point.topLeftFromJson(json) + // . .frame.bottomRight = Point.bottomRightFromJson(json) ..originalRef = json; @override PBIntermediateNode createIntermediateNode(Map json) => (InheritedBitmap.fromJson(json) as InheritedBitmap)..originalRef = json; + } diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart index 79562cfa..a493573a 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart @@ -9,31 +9,14 @@ part of 'inherited_bitmap.dart'; InheritedBitmap _$InheritedBitmapFromJson(Map json) { return InheritedBitmap( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'] as String, referenceImage: json['imageReference'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -43,20 +26,12 @@ InheritedBitmap _$InheritedBitmapFromJson(Map json) { Map _$InheritedBitmapToJson(InheritedBitmap instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'children': instance.children, - 'child': instance.child, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'imageReference': instance.referenceImage, 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 5408fd2d..4b50a06d 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -26,11 +26,7 @@ class InheritedCircle extends PBVisualIntermediateNode @override @JsonKey() String type = 'circle'; - - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - + @override @JsonKey(ignore: true) Map originalRef; @@ -40,15 +36,12 @@ class InheritedCircle extends PBVisualIntermediateNode Rectangle frame, { this.originalRef, String name, - PBContext currentContext, Point alignX, Point alignY, - this.size, this.prototypeNode, }) : super( UUID, frame, - currentContext, name, ) { generator = PBBitmapGenerator(); @@ -63,8 +56,6 @@ class InheritedCircle extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$InheritedCircleFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_circle.g.dart b/lib/interpret_and_optimize/entities/inherited_circle.g.dart index ceb11f78..4300208a 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.g.dart @@ -9,22 +9,13 @@ part of 'inherited_circle.dart'; InheritedCircle _$InheritedCircleFromJson(Map json) { return InheritedCircle( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), - name: json['name'] as String, - size: PBIntermediateNode.sizeFromJson( + DeserializedRectangle.fromJson( json['boundaryRectangle'] as Map), + name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -34,17 +25,11 @@ InheritedCircle _$InheritedCircleFromJson(Map json) { Map _$InheritedCircleToJson(InheritedCircle instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index df4d06ec..e2ebac2a 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -34,34 +34,22 @@ class InheritedContainer extends PBVisualIntermediateNode @JsonKey() String type = 'rectangle'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - @override @JsonKey(ignore: true) Map originalRef; - @override - @JsonKey(ignore: true) - List get children => null; - InheritedContainer( String UUID, Rectangle frame, { this.originalRef, - Rectangle rectangle, String name, double alignX, double alignY, - PBContext currentContext, this.isBackgroundVisible = true, - this.size, this.prototypeNode, }) : super( UUID, - rectangle, - currentContext, + frame, name, ) { generator = PBContainerGenerator(); @@ -75,8 +63,6 @@ class InheritedContainer extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) { var container = _$InheritedContainerFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; container.mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/inherited_container.g.dart b/lib/interpret_and_optimize/entities/inherited_container.g.dart index 32efb717..910f9dc0 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.g.dart @@ -9,23 +9,14 @@ part of 'inherited_container.dart'; InheritedContainer _$InheritedContainerFromJson(Map json) { return InheritedContainer( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'] as String, isBackgroundVisible: json['isBackgroundVisible'] as bool ?? true, - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -35,18 +26,12 @@ InheritedContainer _$InheritedContainerFromJson(Map json) { Map _$InheritedContainerToJson(InheritedContainer instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'isBackgroundVisible': instance.isBackgroundVisible, 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index 8020d5b2..273ef014 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -32,10 +32,6 @@ class InheritedOval extends PBVisualIntermediateNode @JsonKey() String type = 'oval'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - @override @JsonKey(ignore: true) Map originalRef; @@ -46,20 +42,19 @@ class InheritedOval extends PBVisualIntermediateNode this.originalRef, String name, Uint8List image, - PBContext currentContext, this.prototypeNode, - this.size, - }) : super(UUID, frame, currentContext, name) { + }) : super(UUID, frame, name) { generator = PBBitmapGenerator(); - - ImageReferenceStorage().addReferenceAndWrite( - UUID, '${MainInfo().outputPath}assets/images', image); + if (image != null) { + ImageReferenceStorage().addReferenceAndWrite( + UUID, '${MainInfo().outputPath}assets/images', image); + } } static PBIntermediateNode fromJson(Map json) => _$InheritedOvalFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) + // . .frame.topLeft = Point.topLeftFromJson(json) + // . .frame.bottomRight = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_oval.g.dart b/lib/interpret_and_optimize/entities/inherited_oval.g.dart index d4d6a670..769305a4 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.g.dart @@ -9,30 +9,13 @@ part of 'inherited_oval.dart'; InheritedOval _$InheritedOvalFromJson(Map json) { return InheritedOval( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -42,19 +25,11 @@ InheritedOval _$InheritedOvalFromJson(Map json) { Map _$InheritedOvalToJson(InheritedOval instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'children': instance.children, - 'child': instance.child, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index c865e37d..cae5ba68 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -33,38 +33,33 @@ class InheritedPolygon extends PBVisualIntermediateNode @JsonKey() String type = 'polygon'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - @override @JsonKey(ignore: true) Map originalRef; - InheritedPolygon(String UUID, Rectangle frame,{ + InheritedPolygon( + String UUID, + Rectangle frame, { this.originalRef, name, Uint8List image, - PBContext currentContext, this.prototypeNode, - this.size, }) : super( UUID, frame, - currentContext, name, ) { generator = PBBitmapGenerator(); childrenStrategy = NoChildStrategy(); - ImageReferenceStorage().addReferenceAndWrite( - UUID, '${MainInfo().outputPath}assets/images', image); + if (image != null) { + ImageReferenceStorage().addReferenceAndWrite( + UUID, '${MainInfo().outputPath}assets/images', image); + } } static PBIntermediateNode fromJson(Map json) => _$InheritedPolygonFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart index b8e75830..99f3cb96 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart @@ -9,30 +9,13 @@ part of 'inherited_polygon.dart'; InheritedPolygon _$InheritedPolygonFromJson(Map json) { return InheritedPolygon( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'], prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -42,19 +25,11 @@ InheritedPolygon _$InheritedPolygonFromJson(Map json) { Map _$InheritedPolygonToJson(InheritedPolygon instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'children': instance.children, - 'child': instance.child, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 7f3cb5a4..f1a72531 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -8,7 +8,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; @@ -38,129 +37,109 @@ class InheritedScaffold extends PBVisualIntermediateNode @JsonKey() String type = 'artboard'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - @override - @JsonKey(ignore: true) - PBIntermediateNode get child => getAttributeNamed('body')?.attributeNode; - - @override - List get children => [child, navbar, tabbar]; - - PBIntermediateNode get navbar => getAttributeNamed('appBar')?.attributeNode; + PBIntermediateNode get navbar => getAttributeNamed('appBar'); - PBIntermediateNode get tabbar => - getAttributeNamed('bottomNavigationBar')?.attributeNode; + PBIntermediateNode get tabbar => getAttributeNamed('bottomNavigationBar'); @override - set child(PBIntermediateNode node) { - if (!hasAttribute('body')) { - addAttribute(PBAttribute('body', attributeNodes: [node])); - } else { - getAttributeNamed('body').attributeNode = node; - } - } - - @override - @JsonKey(ignore: true) Map originalRef; InheritedScaffold( - String UUID, - Rectangle frame, { - this.originalRef, - String name, - PBContext currentContext, - this.isHomeScreen, - this.prototypeNode, - this.size, - }) : super( - UUID, - frame, - currentContext, - name, - ) { - this.name = name - ?.replaceAll(RegExp(r'[\W]'), '') - ?.replaceFirst(RegExp(r'^([\d]|_)+'), ''); - + String UUID, Rectangle frame, String name, this.originalRef, + {this.isHomeScreen, this.prototypeNode}) + : super(UUID, frame, name) { generator = PBScaffoldGenerator(); - - //TODO switch to padding strategy - - // Add body attribute - addAttribute(PBAttribute('body')); - } - - List layoutInstruction(List layer) { - return layer; } @override - void addChild(node) { - print(this.name); - if (this.name == 'ArtboardTRpinnoscale') { - print('object'); - } - if (node is PBSharedInstanceIntermediateNode) { - if (node.name.contains('')) { - addAttribute(PBAttribute('appBar', attributeNodes: [node])); - currentContext.canvasTLC = - Point(currentContext.canvasTLC.x, node.bottomRightCorner.y); - return; - } - if (node.name.contains('')) { - addAttribute( - PBAttribute('bottomNavigationBar', attributeNodes: [node])); - return; - } - } + void addChild(PBIntermediateNode node) { + // if (node is PBSharedInstanceIntermediateNode) { + // if (node.name.contains('')) { + // // this.children.add(); + // // addAttribute(PBAttribute('appBar', attributeNodes: [node])); + // // currentContext.canvasFrame = Rectangle.fromPoints( + // // currentContext.screenFrame.topLeft, node.frame.bottomRight); + // return; + // } + // if (node.name.contains('')) { + // // addAttribute( + // // PBAttribute('bottomNavigationBar', attributeNodes: [node])); + // return; + // } + // } if (node is InjectedAppbar) { - addAttribute(PBAttribute('appBar', attributeNodes: [node])); - currentContext.canvasTLC = - Point(currentContext.canvasTLC.x, node.bottomRightCorner.y); + children.add(node..attributeName = 'appBar'); + // currentContext.canvasFrame = Rectangle.fromPoints( + // currentContext.screenFrame.topLeft, node.frame.bottomRight); return; } if (node is InjectedTabBar) { - addAttribute(PBAttribute('bottomNavigationBar', attributeNodes: [node])); + children.add(node..attributeName = 'bottomNavigationBar'); + // addAttribute(PBAttribute('bottomNavigationBar', attributeNodes: [node])); return; + } else { + children.add(node..attributeName = 'body'); } - if (child is TempGroupLayoutNode) { - child.addChild(node); - return; - } + // if (child is TempGroupLayoutNode) { + // // child.addChild(node); + // return; + // } // If there's multiple children add a temp group so that layout service lays the children out. - if (child != null) { - var temp = TempGroupLayoutNode(null, null, - currentContext: currentContext, name: node.name); - temp.addChild(child); - temp.addChild(node); - child = temp; - } else { - if (child != null) { - child.addChild(node); - } else { - var stack = PBIntermediateStackLayout(currentContext, - name: node.name, - constraints: PBIntermediateConstraints( - pinBottom: false, - pinLeft: false, - pinRight: false, - pinTop: false)); - stack.addChild(node); - child = stack; - } - } + // if (child != null) { + // var temp = TempGroupLayoutNode(null, null, + // currentContext: currentContext, name: node.name); + // temp.addChild(child); + // temp.addChild(node); + // child = temp; + // } else { + // if (child != null) { + // child.addChild(node); + // } else { + // var stack = PBIntermediateStackLayout(currentContext, + // name: node.name, + // constraints: PBIntermediateConstraints( + // pinBottom: false, + // pinLeft: false, + // pinRight: false, + // pinTop: false)); + // var stack = TempGroupLayoutNode(UUID, frame); + // stack.addChild(node); + // child = stack; + // } } + @override + void handleChildren(PBContext context) { + var children = getAllAtrributeNamed('body'); + var groupAtt = TempGroupLayoutNode(null, null)..attributeName = 'body'; + children.forEach((att) => groupAtt.addChild(att)); + + children = [groupAtt]; + + ///get tempgroup + ///add all of the rest of children to it + ///if temp group is null, create group + ///add all of the rest of children + } + + // @override + // @JsonKey(ignore: true) + // PBIntermediateNode get child => getAttributeNamed('body')?.attributeNode; + + // @JsonKey(ignore: true) + // @override + // List get children => [child, navbar, tabbar]; + + List layoutInstruction(List layer) { + return layer; + } + + // } + static PBIntermediateNode fromJson(Map json) { - var artboard = _$InheritedScaffoldFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) - ..originalRef = json; + var artboard = _$InheritedScaffoldFromJson(json)..originalRef = json; //Map artboard children by calling `addChild` method artboard.mapRawChildren(json); @@ -170,4 +149,38 @@ class InheritedScaffold extends PBVisualIntermediateNode @override PBIntermediateNode createIntermediateNode(Map json) => InheritedScaffold.fromJson(json); + + // @override + // set child(PBIntermediateNode node) { + // if (!hasAttribute('body')) { + // addAttribute(PBAttribute('body', attributeNodes: [node])); + // } else { + // getAttributeNamed('body').attributeNode = node; + // } } + +// InheritedScaffold( +// String UUID, +// Rectangle frame, { +// this.originalRef, +// String name, +// this.isHomeScreen, +// this.prototypeNode, +// }) : super( +// UUID, +// frame, +// name, +// ) { +// this.name = name +// ?.replaceAll(RegExp(r'[\W]'), '') +// ?.replaceFirst(RegExp(r'^([\d]|_)+'), ''); + +// generator = PBScaffoldGenerator(); + +// //TODO switch to padding strategy + +// // Add body attribute +// addAttribute(PBAttribute('body')); +// } + + diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart index e5ef9646..30544970 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart @@ -9,50 +9,31 @@ part of 'inherited_scaffold.dart'; InheritedScaffold _$InheritedScaffoldFromJson(Map json) { return InheritedScaffold( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), - name: json['name'] as String, + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), + json['name'] as String, + json['originalRef'] as Map, isHomeScreen: json['isFlowHome'] as bool ?? false, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( json['style'] as Map) - ..type = json['type'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList(); + ..type = json['type'] as String; } Map _$InheritedScaffoldToJson(InheritedScaffold instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'isFlowHome': instance.isHomeScreen, 'type': instance.type, - 'boundaryRectangle': instance.size, - 'children': instance.children, + 'originalRef': instance.originalRef, }; diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index 4655ef72..aa8c90e2 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -32,31 +32,20 @@ class InheritedShapeGroup extends PBVisualIntermediateNode @JsonKey() String type = 'image'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - @override @JsonKey(ignore: true) Map originalRef; - @override - @JsonKey(ignore: true) - List get children => super.children; - InheritedShapeGroup( String UUID, Rectangle frame, { this.originalRef, String name, Uint8List image, - PBContext currentContext, this.prototypeNode, - this.size, }) : super( UUID, frame, - currentContext, name, ) { generator = PBBitmapGenerator(); @@ -68,8 +57,6 @@ class InheritedShapeGroup extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) { var group = _$InheritedShapeGroupFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json; group.mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart index e5389bda..9c60bc07 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart @@ -9,25 +9,13 @@ part of 'inherited_shape_group.dart'; InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { return InheritedShapeGroup( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -38,18 +26,11 @@ InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { Map _$InheritedShapeGroupToJson( InheritedShapeGroup instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'child': instance.child, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index a3a0f9d5..63612f24 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -33,9 +33,6 @@ class InheritedShapePath extends PBVisualIntermediateNode @JsonKey() String type = 'image'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; @override @JsonKey(ignore: true) @@ -47,13 +44,10 @@ class InheritedShapePath extends PBVisualIntermediateNode this.originalRef, String name, Uint8List image, - PBContext currentContext, this.prototypeNode, - this.size, }) : super( UUID, frame, - currentContext, name, ) { generator = PBBitmapGenerator(); @@ -106,8 +100,8 @@ class InheritedShapePath extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$InheritedShapePathFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) + // . .frame.topLeft = Point.topLeftFromJson(json) + // . .frame.bottomRight = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart index 19d0b494..1390b8d2 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart @@ -9,30 +9,13 @@ part of 'inherited_shape_path.dart'; InheritedShapePath _$InheritedShapePathFromJson(Map json) { return InheritedShapePath( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -42,19 +25,11 @@ InheritedShapePath _$InheritedShapePathFromJson(Map json) { Map _$InheritedShapePathToJson(InheritedShapePath instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'children': instance.children, - 'child': instance.child, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index 305d7061..c83d6d69 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -32,9 +32,7 @@ class InheritedStar extends PBVisualIntermediateNode @JsonKey() String type = 'star'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; + @override @JsonKey(ignore: true) @@ -46,13 +44,10 @@ class InheritedStar extends PBVisualIntermediateNode this.originalRef, name, Uint8List image, - PBContext currentContext, this.prototypeNode, - this.size, }) : super( UUID, frame, - currentContext, name, ) { generator = PBBitmapGenerator(); @@ -64,8 +59,8 @@ class InheritedStar extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$InheritedStarFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) + // . .frame.topLeft = Point.topLeftFromJson(json) + // . .frame.bottomRight = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/inherited_star.g.dart b/lib/interpret_and_optimize/entities/inherited_star.g.dart index 6d1baa52..4ffe3b1b 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.g.dart @@ -9,30 +9,13 @@ part of 'inherited_star.dart'; InheritedStar _$InheritedStarFromJson(Map json) { return InheritedStar( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'], prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -42,19 +25,11 @@ InheritedStar _$InheritedStarFromJson(Map json) { Map _$InheritedStarToJson(InheritedStar instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'children': instance.children, - 'child': instance.child, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 53b9120f..02d690f0 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -36,10 +36,6 @@ class InheritedText extends PBVisualIntermediateNode @JsonKey() String type = 'text'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - @JsonKey(name: 'content') String text; @JsonKey(ignore: true) @@ -64,8 +60,6 @@ class InheritedText extends PBVisualIntermediateNode Rectangle frame, { this.originalRef, name, - PBContext currentContext, - this.size, this.alignmenttype, this.fontName, this.fontSize, @@ -79,7 +73,6 @@ class InheritedText extends PBVisualIntermediateNode }) : super( UUID, frame, - currentContext, name, ) { generator = PBTextGen(); @@ -96,8 +89,6 @@ class InheritedText extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$InheritedTextFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json ..fontSize = InheritedTextPBDLHelper.fontSizeFromJson(json) ..fontName = InheritedTextPBDLHelper.fontNameFromJson(json) @@ -115,11 +106,9 @@ class InheritedText extends PBVisualIntermediateNode return InheritedContainer( inheritedText.UUID, inheritedText.frame, - // topLeftCorner: inheritedText.topLeftCorner, - // bottomRightCorner: inheritedText.bottomRightCorner, + // topLeftCorner: inheritedText .frame.topLeft, + // bottomRightCorner: inheritedText .frame.bottomRight, name: inheritedText.name, - currentContext: inheritedText.currentContext, - size: inheritedText.size, originalRef: json, )..addChild(inheritedText); } diff --git a/lib/interpret_and_optimize/entities/inherited_text.g.dart b/lib/interpret_and_optimize/entities/inherited_text.g.dart index 3be8890c..d3c358e5 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.g.dart @@ -9,32 +9,15 @@ part of 'inherited_text.dart'; InheritedText _$InheritedTextFromJson(Map json) { return InheritedText( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), - name: json['name'], - size: PBIntermediateNode.sizeFromJson( + DeserializedRectangle.fromJson( json['boundaryRectangle'] as Map), + name: json['name'], isTextParameter: json['isTextParameter'] as bool ?? false, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), text: json['content'] as String, ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -44,21 +27,13 @@ InheritedText _$InheritedTextFromJson(Map json) { Map _$InheritedTextToJson(InheritedText instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'children': instance.children, - 'child': instance.child, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'isTextParameter': instance.isTextParameter, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'boundaryRectangle': instance.size, 'content': instance.text, }; diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 3e6b6dc5..9f3fa8ae 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -33,10 +33,6 @@ class InheritedTriangle extends PBVisualIntermediateNode @JsonKey() String type = 'triangle'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - @override @JsonKey(ignore: true) Map originalRef; @@ -47,13 +43,10 @@ class InheritedTriangle extends PBVisualIntermediateNode this.originalRef, String name, Uint8List image, - PBContext currentContext, this.prototypeNode, - this.size, }) : super( UUID, frame, - currentContext, name, ) { generator = PBBitmapGenerator(); @@ -64,10 +57,7 @@ class InheritedTriangle extends PBVisualIntermediateNode } static PBIntermediateNode fromJson(Map json) => - _$InheritedTriangleFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) - ..originalRef = json; + _$InheritedTriangleFromJson(json)..originalRef = json; @override PBIntermediateNode createIntermediateNode(Map json) => diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart index c6332ec8..4537201e 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart @@ -9,30 +9,13 @@ part of 'inherited_triangle.dart'; InheritedTriangle _$InheritedTriangleFromJson(Map json) { return InheritedTriangle( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -42,19 +25,11 @@ InheritedTriangle _$InheritedTriangleFromJson(Map json) { Map _$InheritedTriangleToJson(InheritedTriangle instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'children': instance.children, - 'child': instance.child, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 536ad4b6..bdee3543 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -29,13 +29,10 @@ class InjectedContainer extends PBVisualIntermediateNode @override @JsonKey(fromJson: PrototypeNode.prototypeNodeFromJson) PrototypeNode prototypeNode; - ChildrenStrategy childrenStrategy = TempChildrenStrategy('child'); + @override @JsonKey() String type = 'injected_container'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson) - Map size; InjectedContainer( UUID, @@ -44,22 +41,15 @@ class InjectedContainer extends PBVisualIntermediateNode double alignX, double alignY, String color, - PBContext currentContext, this.prototypeNode, - this.size, this.type, }) : super( UUID, frame, - currentContext, - name, + name, ) { generator = PBContainerGenerator(); - - size = { - 'width': (bottomRightCorner.x - topLeftCorner.x).abs(), - 'height': (bottomRightCorner.y - topLeftCorner.y).abs(), - }; + childrenStrategy = TempChildrenStrategy('child'); } static PBIntermediateNode fromJson(Map json) => diff --git a/lib/interpret_and_optimize/entities/injected_container.g.dart b/lib/interpret_and_optimize/entities/injected_container.g.dart index 8b59ffc0..ed0f3e6d 100644 --- a/lib/interpret_and_optimize/entities/injected_container.g.dart +++ b/lib/interpret_and_optimize/entities/injected_container.g.dart @@ -9,22 +9,14 @@ part of 'injected_container.dart'; InjectedContainer _$InjectedContainerFromJson(Map json) { return InjectedContainer( json['UUID'], - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson(json['prototypeNode'] as String), - size: PBIntermediateNode.sizeFromJson(json['size'] as Map), type: json['type'] as String, ) - ..parent = json['parent'] == null - ? null - : PBIntermediateNode.fromJson(json['parent'] as Map) - ..treeLevel = json['treeLevel'] as int ..subsemantic = json['subsemantic'] as String - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -33,17 +25,11 @@ InjectedContainer _$InjectedContainerFromJson(Map json) { Map _$InjectedContainerToJson(InjectedContainer instance) => { - 'parent': instance.parent, - 'treeLevel': instance.treeLevel, 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNode': instance.prototypeNode, 'type': instance.type, - 'size': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/layouts/column.dart b/lib/interpret_and_optimize/entities/layouts/column.dart index 55d5587a..016c07c1 100644 --- a/lib/interpret_and_optimize/entities/layouts/column.dart +++ b/lib/interpret_and_optimize/entities/layouts/column.dart @@ -1,4 +1,4 @@ -import 'dart:html'; +import 'dart:math'; import 'package:parabeac_core/generation/generators/layouts/pb_column_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; @@ -30,24 +30,19 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { @override AlignStrategy alignStrategy = ColumnAlignment(); - PBIntermediateColumnLayout(PBContext currentContext, Rectangle frame, - {String name}) - : super(null, frame, COLUMN_RULES, COLUMN_EXCEPTIONS, currentContext, - name) { + PBIntermediateColumnLayout(Rectangle frame, {String name}) + : super(null, frame, COLUMN_RULES, COLUMN_EXCEPTIONS, name) { generator = PBColumnGenerator(); } @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { - var col = PBIntermediateColumnLayout(currentContext, null, name: name); + var col = PBIntermediateColumnLayout(null, name: name); col.prototypeNode = prototypeNode; children.forEach((child) => col.addChild(child)); return col; } - - @override - void addChild(node) => addChildToLayout(node); } class ColumnAlignment extends AlignStrategy { @@ -65,38 +60,41 @@ class ColumnAlignment extends AlignStrategy { void align(PBContext context, PBIntermediateColumnLayout node) { node.checkCrossAxisAlignment(); _invertAlignment(node); - if (node.currentContext.configuration.widgetSpacing == 'Expanded') { - _addPerpendicularAlignment(node); - _addParallelAlignment(node); + if (context.configuration.widgetSpacing == 'Expanded') { + _addPerpendicularAlignment(node, context); + _addParallelAlignment(node, context); } else { assert(false, - 'We don\'t support Configuration [${node.currentContext.configuration.widgetSpacing}] yet.'); + 'We don\'t support Configuration [${context.configuration.widgetSpacing}] yet.'); } } - void _addParallelAlignment(PBIntermediateColumnLayout node) { - var newchildren = handleFlex(true, node.topLeftCorner, - node.bottomRightCorner, node.children?.cast()); - node.replaceChildren(newchildren); + void _addParallelAlignment( + PBIntermediateColumnLayout node, PBContext context) { + var newchildren = handleFlex(true, node.frame.topLeft, + node.frame.bottomRight, node.children?.cast()); + node.replaceChildren(newchildren, context); } - void _addPerpendicularAlignment(PBIntermediateColumnLayout node) { - var columnMinX = node.topLeftCorner.x; - var columnMaxX = node.bottomRightCorner.x; + void _addPerpendicularAlignment( + PBIntermediateColumnLayout node, PBContext context) { + var columnMinX = node.frame.topLeft.x; + var columnMaxX = node.frame.bottomRight.x; for (var i = 0; i < node.children.length; i++) { - var padding = Padding(null, node.frame, node.children[i].constraints, - left: node.children[i].topLeftCorner.x - columnMinX ?? 0.0, - right: columnMaxX - node.children[i].bottomRightCorner.x ?? 0.0, - top: 0.0, - bottom: 0.0, - currentContext: node.currentContext); + var padding = Padding( + null, + node.frame, + node.children[i].constraints, + left: node.children[i].frame.topLeft.x - columnMinX ?? 0.0, + right: columnMaxX - node.children[i].frame.bottomRight.x ?? 0.0, + top: 0.0, + bottom: 0.0, + ); padding.addChild(node.children[i]); //Replace Children. - var childrenCopy = node.children; - childrenCopy[i] = padding; - node.replaceChildren(childrenCopy?.cast()); + node.children[i] = padding; } } diff --git a/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart b/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart index 676c1c70..e1d87092 100644 --- a/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart +++ b/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart @@ -11,10 +11,10 @@ class ColumnOverlappingException extends LayoutException bool testException( PBIntermediateNode currentNode, PBIntermediateNode incomingNode) { return (areXCoordinatesOverlapping( - currentNode.topLeftCorner, - currentNode.bottomRightCorner, - incomingNode.topLeftCorner, - currentNode.bottomRightCorner) && + currentNode.frame.topLeft, + currentNode.frame.bottomRight, + incomingNode.frame.topLeft, + currentNode.frame.bottomRight) && (currentNode is PBLayoutIntermediateNode && currentNode is! TempGroupLayoutNode && currentNode is! PBIntermediateStackLayout)); @@ -26,10 +26,10 @@ class RowOverlappingException extends LayoutException with AxisComparisonRule { bool testException( PBIntermediateNode currentNode, PBIntermediateNode incomingNode) { return (areYCoordinatesOverlapping( - currentNode.topLeftCorner, - currentNode.bottomRightCorner, - incomingNode.topLeftCorner, - incomingNode.bottomRightCorner) && + currentNode.frame.topLeft, + currentNode.frame.bottomRight, + incomingNode.frame.topLeft, + incomingNode.frame.bottomRight) && (currentNode is PBLayoutIntermediateNode && currentNode is! TempGroupLayoutNode && currentNode is! PBIntermediateStackLayout)); diff --git a/lib/interpret_and_optimize/entities/layouts/row.dart b/lib/interpret_and_optimize/entities/layouts/row.dart index ef865411..955bf599 100644 --- a/lib/interpret_and_optimize/entities/layouts/row.dart +++ b/lib/interpret_and_optimize/entities/layouts/row.dart @@ -26,80 +26,78 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { @override AlignStrategy alignStrategy = RowAlignment(); - PBIntermediateRowLayout(PBContext currentContext, {String name}) - : super(null, null, ROW_RULES, ROW_EXCEPTIONS, currentContext, name) { + PBIntermediateRowLayout({String name}) + : super(null, null, ROW_RULES, ROW_EXCEPTIONS, name) { generator = PBRowGenerator(); } - @override - void addChild(node) => addChildToLayout(node); - @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { - var row = PBIntermediateRowLayout(currentContext, name: name); + var row = PBIntermediateRowLayout(name: name); row.prototypeNode = prototypeNode; children.forEach((child) => row.addChild(child)); return row; } - @override - void sortChildren() => replaceChildren(children - ..sort((child0, child1) => - child0.topLeftCorner.x.compareTo(child1.topLeftCorner.x))); + // @override + // void sortChildren() => replaceChildren(children + // ..sort((child0, child1) => + // child0..frame.topLeft.x.compareTo(child1.frame.topLeft.x))); } class RowAlignment extends AlignStrategy { @override void align(PBContext context, PBIntermediateRowLayout node) { node.checkCrossAxisAlignment(); - if (node.currentContext.configuration.widgetSpacing == 'Expanded') { - _addPerpendicularAlignment(node); - _addParallelAlignment(node); + if (context.configuration.widgetSpacing == 'Expanded') { + _addPerpendicularAlignment(node, context); + _addParallelAlignment(node, context); } else { assert(false, - 'We don\'t support Configuration [${node.currentContext.configuration.widgetSpacing}] yet.'); + 'We don\'t support Configuration [${context.configuration.widgetSpacing}] yet.'); } } - void _addParallelAlignment(PBIntermediateRowLayout node) { - var newchildren = handleFlex(false, node.topLeftCorner, - node.bottomRightCorner, node.children?.cast()); - node.replaceChildren(newchildren); + void _addParallelAlignment(PBIntermediateRowLayout node, PBContext context) { + var newchildren = handleFlex(false, node.frame.topLeft, + node.frame.bottomRight, node.children?.cast()); + node.replaceChildren(newchildren, context); } - void _addPerpendicularAlignment(PBIntermediateRowLayout node) { - var rowMinY = node.topLeftCorner.y; - var rowMaxY = node.bottomRightCorner.y; + void _addPerpendicularAlignment( + PBIntermediateRowLayout node, PBContext context) { + var rowMinY = node.frame.topLeft.y; + var rowMaxY = node.frame.bottomRight.y; - if (node.topLeftCorner.y < node.currentContext.screenTopLeftCorner.y) { - rowMinY = node.currentContext.screenTopLeftCorner.y; + if (node.frame.topLeft.y < context.screenFrame.topLeft.y) { + rowMinY = context.screenFrame.topLeft.y; } - if (node.bottomRightCorner.y > - node.currentContext.screenBottomRightCorner.y) { - rowMaxY = node.currentContext.screenBottomRightCorner.y; + if (node.frame.bottomRight.y > context.screenFrame.bottomRight.y) { + rowMaxY = context.screenFrame.bottomRight.y; } for (var i = 0; i < node.children.length; i++) { - var padding = Padding(null, node.frame, node.children[i].constraints, - top: node.children[i].topLeftCorner.y - rowMinY ?? 0.0, - bottom: rowMaxY - node.children[i].bottomRightCorner.y ?? 0.0, - left: 0.0, - right: 0.0, - currentContext: node.currentContext); + var padding = Padding( + null, + node.frame, + node.children[i].constraints, + top: node.children[i].frame.topLeft.y - rowMinY ?? 0.0, + bottom: rowMaxY - node.children[i].frame.bottomRight.y ?? 0.0, + left: 0.0, + right: 0.0, + ); padding.addChild(node.children[i]); //Replace Children. - var childrenCopy = node.children; - childrenCopy[i] = padding; - node.replaceChildren(childrenCopy); + node.children[i] = padding; } } @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { - var row = PBIntermediateRowLayout(currentContext, name: name); + var row = PBIntermediateRowLayout(name: name); // row.prototypeNode = prototypeNode; children.forEach((child) => row.addChild(child)); return row; @@ -108,7 +106,7 @@ class RowAlignment extends AlignStrategy { // @override // void sortChildren() => replaceChildren(children // ..sort((child0, child1) => - // child0.topLeftCorner.x.compareTo(child1.topLeftCorner.x))); + // child0 .frame.topLeft.x.compareTo(child1 .frame.topLeft.x))); @override PBIntermediateNode fromJson(Map json) => null; diff --git a/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart b/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart index 832afe6f..4ee3ab50 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart @@ -36,15 +36,15 @@ class HorizontalNodesLayoutRule extends LayoutRule with AxisComparisonRule { @override bool testRule(PBIntermediateNode currentNode, PBIntermediateNode nextNode) => (!(areXCoordinatesOverlapping( - currentNode.topLeftCorner, - currentNode.bottomRightCorner, - nextNode.topLeftCorner, - nextNode.bottomRightCorner))) && + currentNode .frame.topLeft, + currentNode .frame.bottomRight, + nextNode .frame.topLeft, + nextNode .frame.bottomRight))) && areYCoordinatesOverlapping( - currentNode.topLeftCorner, - currentNode.bottomRightCorner, - nextNode.topLeftCorner, - nextNode.bottomRightCorner); + currentNode .frame.topLeft, + currentNode .frame.bottomRight, + nextNode .frame.topLeft, + nextNode .frame.bottomRight); } ///Returns if the points [topLeftCorner0] and [bottomRightCorner0] @@ -54,28 +54,30 @@ class VerticalNodesLayoutRule extends LayoutRule with AxisComparisonRule { @override bool testRule(PBIntermediateNode currentNode, PBIntermediateNode nextNode) => (!(areYCoordinatesOverlapping( - currentNode.topLeftCorner, - currentNode.bottomRightCorner, - nextNode.topLeftCorner, - nextNode.bottomRightCorner))) && + currentNode .frame.topLeft, + currentNode .frame.bottomRight, + nextNode .frame.topLeft, + nextNode .frame.bottomRight))) && areXCoordinatesOverlapping( - currentNode.topLeftCorner, - currentNode.bottomRightCorner, - nextNode.topLeftCorner, - nextNode.bottomRightCorner); + currentNode .frame.topLeft, + currentNode .frame.bottomRight, + nextNode .frame.topLeft, + nextNode .frame.bottomRight); } class OverlappingNodesLayoutRule extends LayoutRule with AxisComparisonRule { @override bool testRule(PBIntermediateNode currentNode, PBIntermediateNode nextNode) => - (areXCoordinatesOverlapping( - currentNode.topLeftCorner, - currentNode.bottomRightCorner, - nextNode.topLeftCorner, - nextNode.bottomRightCorner)) && - areYCoordinatesOverlapping( - currentNode.topLeftCorner, - currentNode.bottomRightCorner, - nextNode.topLeftCorner, - nextNode.bottomRightCorner); + currentNode.frame.containsPoint(nextNode.frame.topLeft) || + currentNode.frame.containsPoint(nextNode.frame.bottomRight); + // (areXCoordinatesOverlapping( + // currentNode .frame.topLeft, + // currentNode .frame.bottomRight, + // nextNode .frame.topLeft, + // nextNode .frame.bottomRight)) && + // areYCoordinatesOverlapping( + // currentNode .frame.topLeft, + // currentNode .frame.bottomRight, + // nextNode .frame.topLeft, + // nextNode .frame.bottomRight); } diff --git a/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart index 6e098bcd..85d06eb3 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart @@ -11,7 +11,6 @@ class ContainerConstraintRule extends PostConditionRule { if (testRule(currentNode, nextNode)) { var container = InjectedContainer(null, currentNode.frame, name: currentNode.name, - currentContext: currentNode.currentContext, // constraints: currentNode.constraints ); container.addChild(currentNode); diff --git a/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart index 54ac04e2..85e330a4 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart @@ -33,7 +33,7 @@ class ContainerPostRule extends PostConditionRule { pbvisual = children .firstWhere((element) => element is PBVisualIntermediateNode); return overlappingNodesLayoutRule.testRule(pbvisual, pblayout) && - (pbvisual as PBVisualIntermediateNode).child == null; + (pbvisual as PBVisualIntermediateNode).children.isNotEmpty; } } return false; diff --git a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart index f99c8677..43ddac6f 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dar import 'package:parabeac_core/interpret_and_optimize/entities/layouts/row.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/column.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; import 'package:uuid/uuid.dart'; @@ -38,26 +39,26 @@ List handleFlex(bool isVertical, Point topLeft, var prevChild = children[i - 1]; var spacerLength = isVertical - ? _calculateHeight(prevChild.bottomRightCorner, child.topLeftCorner) - : _calculateWidth(prevChild.bottomRightCorner, child.topLeftCorner); + ? _calculateHeight(prevChild.frame.bottomRight, child.frame.topLeft) + : _calculateWidth(prevChild.frame.bottomRight, child.frame.topLeft); if (spacerLength > 0) { var flex = _calculateFlex(spacerLength, parentLength); resultingChildren.add(Spacer( - null, - Rectangle.fromPoints( - isVertical - ? Point(prevChild.topLeftCorner.x, - prevChild.bottomRightCorner.y) - : Point(prevChild.bottomRightCorner.x, - prevChild.topLeftCorner.y), - isVertical - ? Point(child.bottomRightCorner.x, child.topLeftCorner.y) - : Point(child.topLeftCorner.x, - child.bottomRightCorner.y)), //brc + null, + Rectangle.fromPoints( + isVertical + ? Point( + prevChild.frame.topLeft.x, prevChild.frame.bottomRight.y) + : Point( + prevChild.frame.bottomRight.x, prevChild.frame.topLeft.y), + isVertical + ? Point(child.frame.bottomRight.x, child.frame.topLeft.y) + : Point( + child.frame.topLeft.x, child.frame.bottomRight.y)), //brc - flex: flex, - currentContext: children.first.currentContext)); + flex: flex, + )); } } @@ -80,10 +81,9 @@ PBIntermediateNode _putChildInFlex( bool isVertical, PBIntermediateNode child, double parentLength) { //Calculate child flex var widgetLength = isVertical - ? _calculateHeight(child.topLeftCorner, child.bottomRightCorner) - : _calculateWidth(child.topLeftCorner, child.bottomRightCorner); + ? _calculateHeight(child.frame.topLeft, child.frame.bottomRight) + : _calculateWidth(child.frame.topLeft, child.frame.bottomRight); var flex = _calculateFlex(widgetLength.abs(), parentLength.abs()); - return Flexible(null, child.frame, - currentContext: child.currentContext, child: child, flex: flex); + return Flexible(null, child.frame, child: child, flex: flex); } diff --git a/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart index 8f287b08..9607aec9 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart @@ -23,10 +23,10 @@ class StackReductionVisualRule extends PostConditionRule { currentNode is PBIntermediateStackLayout ? currentNode : nextNode; var wrapper = (layout as PBIntermediateStackLayout).children.firstWhere( (element) => - element is PBVisualIntermediateNode && element.child == null); + element is PBVisualIntermediateNode && element.children.isEmpty); var child = (layout as PBIntermediateStackLayout).children.firstWhere( (element) => - element is PBVisualIntermediateNode && element.child != null); + element is PBVisualIntermediateNode && element.children.isEmpty); wrapper.addChild(child); if ((layout as PBIntermediateStackLayout).prototypeNode != null) { @@ -59,14 +59,16 @@ class StackReductionVisualRule extends PostConditionRule { children[0] is PBVisualIntermediateNode && children[1] is PBVisualIntermediateNode) { return _overlappingNodesLayoutRule.testRule(children[0], children[1]) && - ((_isEmptyContainer(children[0]) && children[1].child != null) || - (_isEmptyContainer(children[0]) && children[0].child != null)); + ((_isEmptyContainer(children[0]) && + children[1].children.isNotEmpty) || + (_isEmptyContainer(children[0]) && + children[0].children.isNotEmpty)); } return false; } /// Returns true if `node` is a Container with a null child bool _isEmptyContainer(PBVisualIntermediateNode node) => - node.child == null && + node.children.isEmpty && (node is InheritedContainer || node is InjectedContainer); } diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 83693d5b..61a580d4 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:parabeac_core/generation/generators/layouts/pb_stack_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; @@ -21,30 +23,25 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { @override PrototypeNode prototypeNode; - - PBIntermediateStackLayout(PBContext currentContext, + PBIntermediateStackLayout( {String name, PBIntermediateConstraints constraints}) - : super(null, null, STACK_RULES, [], currentContext, name, constraints: constraints) { + : super(null, null, STACK_RULES, [], name, constraints: constraints) { generator = PBStackGenerator(); alignStrategy = PositionedAlignment(); } @override - void addChild(node) => addChildToLayout(node); - - @override - void resize() { - var depth = currentContext.tree?.depthOf(this); + void resize(PBContext context) { + var depth = context.tree?.depthOf(this); /// Since there are cases where [Stack] are being created, and /// childrend are being populated, and consequently [Stack.resize] is being /// called, then [depth] could be null. [depth] is null when the [PBIntermediateTree] /// has not finished creating and converting PBDL nodes into [PBIntermediateNode]. if (depth != null && depth <= 1 && depth >= 0) { - topLeftCorner = currentContext.canvasTLC; - bottomRightCorner = currentContext.canvasBRC; + frame = context.canvasFrame; } else { - super.resize(); + super.resize(context); } } @@ -52,7 +49,7 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { /// The width of this stack must be the full width of the Scaffold or Artboard. As discussed, at some point we can change this but for now, this makes the most sense. - var stack = PBIntermediateStackLayout(currentContext, name: name); + var stack = PBIntermediateStackLayout(name: name); stack.prototypeNode = prototypeNode; children.forEach((child) => stack.addChild(child)); return stack; diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index 23b124bc..d151a255 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -29,10 +29,6 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode @JsonKey() String type = 'group'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - @override Map originalRef; @@ -40,16 +36,9 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode String UUID, Rectangle frame, { this.originalRef, - PBContext currentContext, String name, this.prototypeNode, - this.size, - }) : super(UUID, frame, [], [], currentContext, name); - - @override - void addChild(node) { - addChildToLayout(node); - } + }) : super(UUID, frame, [], [], name); @override bool satisfyRules( @@ -67,8 +56,8 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode static PBIntermediateNode fromJson(Map json) { var tempGroup = _$TempGroupLayoutNodeFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) + // . .frame.topLeft = Point.topLeftFromJson(json) + // . .frame.bottomRight = Point.bottomRightFromJson(json) ..originalRef = json; tempGroup.mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart index d7400d94..f6ad8850 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart @@ -9,21 +9,13 @@ part of 'temp_group_layout_node.dart'; TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { return TempGroupLayoutNode( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) ..subsemantic = json['subsemantic'] as String - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -36,14 +28,9 @@ Map _$TempGroupLayoutNodeToJson( { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'child': instance.child?.toJson(), - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode?.toJson(), 'type': instance.type, - 'boundaryRectangle': instance.size, }; diff --git a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart index 32c57d7f..296e6adc 100644 --- a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart +++ b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart @@ -14,12 +14,10 @@ class PBDenyListNode extends PBIntermediateNode { String UUID, Rectangle frame, { String name, - PBContext currentContext, }) : super( UUID, frame, name, - currentContext: currentContext, ); @override diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index ae1e7e6d..9a7bf63e 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -49,9 +49,6 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @JsonKey() String type = 'shared_instance'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; List overrideValues; // quick lookup based on UUID_type @@ -67,15 +64,12 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode this.originalRef, this.SYMBOL_ID, this.sharedParamValues, - PBContext currentContext, this.prototypeNode, - this.size, this.overrideValues, String name, }) : super( UUID, frame, - currentContext, name, ) { generator = PBSymbolInstanceGenerator(); @@ -94,8 +88,8 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) => _$PBSharedInstanceIntermediateNodeFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) + // . .frame.topLeft = Point.topLeftFromJson(json) + // . .frame.bottomRight = Point.bottomRightFromJson(json) ..originalRef = json; @override diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart index 782cde15..34715b23 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart @@ -10,7 +10,8 @@ PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( Map json) { return PBSharedInstanceIntermediateNode( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), SYMBOL_ID: json['symbolID'] as String, sharedParamValues: (json['overrideValues'] as List) ?.map((e) => e == null @@ -19,23 +20,9 @@ PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( ?.toList(), prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), name: json['name'] as String, ) ..subsemantic = json['subsemantic'] as String - ..children = (json['children'] as List) - ?.map((e) => e == null - ? null - : PBIntermediateNode.fromJson(e as Map)) - ?.toList() - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -48,12 +35,7 @@ Map _$PBSharedInstanceIntermediateNodeToJson( { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'children': instance.children?.map((e) => e?.toJson())?.toList(), - 'child': instance.child?.toJson(), - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'symbolID': instance.SYMBOL_ID, @@ -61,7 +43,6 @@ Map _$PBSharedInstanceIntermediateNodeToJson( instance.sharedParamValues?.map((e) => e?.toJson())?.toList(), 'prototypeNodeUUID': instance.prototypeNode?.toJson(), 'type': instance.type, - 'boundaryRectangle': instance.size, }; PBSharedParameterValue _$PBSharedParameterValueFromJson( diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index cc912ec5..30db0070 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/override_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; @@ -35,26 +36,22 @@ class PBSharedMasterNode extends PBVisualIntermediateNode @JsonKey() String type = 'shared_master'; - @override - @JsonKey(fromJson: PBIntermediateNode.sizeFromJson, name: 'boundaryRectangle') - Map size; - List parametersDefinition; Map parametersDefsMap = {}; ///The children that makes the UI of the [PBSharedMasterNode]. The children are going to be wrapped ///using a [TempGroupLayoutNode] as the root Node. - set children(List children) { - child ??= TempGroupLayoutNode(null, null, - currentContext: currentContext, name: name); - if (child is PBLayoutIntermediateNode) { - children.forEach((element) => child.addChild(element)); - } else { - child = TempGroupLayoutNode(null, null, - currentContext: currentContext, name: name) - ..replaceChildren([child, ...children]); - } - } + // set children(List children) { + // child ??= TempGroupLayoutNode(null, null, + // currentContext: currentContext, name: name); + // if (child is PBLayoutIntermediateNode) { + // children.forEach((element) => child.addChild(element)); + // } else { + // child = TempGroupLayoutNode(null, null, + // currentContext: currentContext, name: name) + // ..replaceChildren([child, ...children]); + // } + // } ///The properties that could be be overridable on a [PBSharedMasterNode] @JsonKey(name: 'overrideProperties') @@ -72,13 +69,10 @@ class PBSharedMasterNode extends PBVisualIntermediateNode this.SYMBOL_ID, String name, this.overridableProperties, - PBContext currentContext, this.prototypeNode, - this.size, }) : super( UUID, frame, - currentContext, name, ) { overridableProperties ??= []; @@ -102,6 +96,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode } generator = PBMasterSymbolGenerator(); + childrenStrategy = TempChildrenStrategy('child'); overridableProperties.forEach(OverrideHelper.addProperty); @@ -132,13 +127,8 @@ class PBSharedMasterNode extends PBVisualIntermediateNode // ..removeWhere((p) => p == null || p.parameterDefinition == null); } - @override - void addChild(node) => child == null ? child = node : children = [node]; - static PBIntermediateNode fromJson(Map json) => _$PBSharedMasterNodeFromJson(json) - // ..topLeftCorner = Point.topLeftFromJson(json) - // ..bottomRightCorner = Point.bottomRightFromJson(json) ..originalRef = json ..mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart index 4101b5db..0b579a6f 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart @@ -9,7 +9,8 @@ part of 'pb_shared_master_node.dart'; PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { return PBSharedMasterNode( json['UUID'] as String, - DeserializedRectangle.fromJson(json['frame'] as Map), + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), SYMBOL_ID: json['symbolID'] as String, name: json['name'] as String, overridableProperties: (json['overrideProperties'] as List) @@ -19,17 +20,8 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { ?.toList(), prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - size: PBIntermediateNode.sizeFromJson( - json['boundaryRectangle'] as Map), ) ..subsemantic = json['subsemantic'] as String - ..child = json['child'] == null - ? null - : PBIntermediateNode.fromJson(json['child'] as Map) - ..topLeftCorner = PBPointLegacyMethod.topLeftFromJson( - json['topLeftCorner'] as Map) - ..bottomRightCorner = PBPointLegacyMethod.bottomRightFromJson( - json['bottomRightCorner'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -41,17 +33,12 @@ Map _$PBSharedMasterNodeToJson(PBSharedMasterNode instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'child': instance.child?.toJson(), - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode?.toJson(), 'symbolID': instance.SYMBOL_ID, 'type': instance.type, - 'boundaryRectangle': instance.size, 'overrideProperties': instance.overridableProperties?.map((e) => e?.toJson())?.toList(), }; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_attribute.dart b/lib/interpret_and_optimize/entities/subclasses/pb_attribute.dart deleted file mode 100644 index 4acb03ad..00000000 --- a/lib/interpret_and_optimize/entities/subclasses/pb_attribute.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - -/// Class that represents an attribute of an IntermediateNode -/// that can have an IntermediateNode inside. `child` or `children` -/// are examples. -class PBAttribute { - List attributeNodes; - - /// To be used for attributes with a single element, sets the first - /// element of `attributeNodes` to `element` - set attributeNode(PBIntermediateNode element) => attributeNodes.isEmpty - ? attributeNodes.add(element) - : attributeNodes.first = element; - - /// To be used for attributes with a single element, gets the first - /// element of `attributeNodes`. - PBIntermediateNode get attributeNode => - attributeNodes.isEmpty ? null : attributeNodes.first; - - /// Name of the attribute. - /// e.g. `child` or `children` - String attributeName; - - PBAttribute( - this.attributeName, { - this.attributeNodes, - }) { - attributeNodes ??= []; - } -} diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 9feac649..4d67ebc1 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -1,8 +1,7 @@ +import 'dart:collection'; import 'dart:math'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; -import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; @@ -21,14 +20,16 @@ import 'package:json_annotation/json_annotation.dart'; part 'pb_intermediate_node.g.dart'; @JsonSerializable( - explicitToJson: true, - createFactory: false, - ignoreUnannotated: true -) -abstract class PBIntermediateNode extends TraversableNode { + explicitToJson: true, createFactory: false, ignoreUnannotated: true) +abstract class PBIntermediateNode extends Iterable + implements TraversableNode { @JsonKey(ignore: true) Logger logger; + @override + @JsonKey(ignore: true) + String attributeName; + /// A subsemantic is contextual info to be analyzed in or in-between the visual generation & layout generation services. String subsemantic; @@ -45,13 +46,37 @@ abstract class PBIntermediateNode extends TraversableNode { /// The key represents the name of the attribute, while the value /// is a List representing the nodes under /// that attribute. - List _attributes; + // @JsonKey( + // name: 'children', + // fromJson: _childrenFromJson, + // toJson: _childrenToJson, + // nullable: true, + // ) + // List _attributes; + + // // TODO(eddie) this is a work around that is currently being tested, delete afterwards + // @JsonKey(name: 'child', fromJson: _childToJson, nullable: true) + // set _child(PBAttribute attribute) { + // _attributes ??= []; + // _attributes.add(attribute); + // } + + // @JsonKey(ignore: true) + // List get attributes => _attributes; + @override + @JsonKey(ignore: true) + PBIntermediateNode parent; + @override @JsonKey(ignore: true) - List get attributes => _attributes; + List children = []; + + @JsonKey(ignore: true) + PBIntermediateNode get child => children.isEmpty ? null : children.first; @override - List get children => [child]; + @JsonKey(ignore: true) + Iterator get iterator => children.iterator; @JsonKey(ignore: true) ChildrenStrategy childrenStrategy = OneChildStrategy('child'); @@ -60,121 +85,104 @@ abstract class PBIntermediateNode extends TraversableNode { AlignStrategy alignStrategy = NoAlignment(); /// Gets the [PBIntermediateNode] at attribute `child` - PBIntermediateNode get child => getAttributeNamed('child')?.attributeNode; + // PBIntermediateNode get child => getAttributeNamed('child')?.attributeNode; /// Sets the `child` attribute's `attributeNode` to `element`. /// If a `child` attribute does not yet exist, it creates it. - set child(PBIntermediateNode element) { - if (element == null) { - return; - } - if (!hasAttribute('child')) { - addAttribute(PBAttribute('child', attributeNodes: [element])); - } else { - getAttributeNamed('child').attributeNode = element; - } - } - - @JsonKey( - fromJson: PBPointLegacyMethod.topLeftFromJson, - toJson: PBPointLegacyMethod.toJson) - Point topLeftCorner; - - @JsonKey( - fromJson: PBPointLegacyMethod.bottomRightFromJson, - toJson: PBPointLegacyMethod.toJson) - Point bottomRightCorner; + // set child(PBIntermediateNode element) { + // if (element == null) { + // return; + // } + // if (!hasAttribute('child')) { + // addAttribute(PBAttribute('child', attributeNodes: [element])); + // } else { + // getAttributeNamed('child').attributeNode = element; + // } + + // } @JsonKey( + ignore: false, + name: 'boundaryRectangle', fromJson: DeserializedRectangle.fromJson, toJson: DeserializedRectangle.toJson) Rectangle frame; - double get width => (bottomRightCorner.x - topLeftCorner.x).toDouble(); - double get height => (bottomRightCorner.y - topLeftCorner.y).toDouble(); - - @JsonKey(ignore: true) - PBContext currentContext; - - @JsonKey(ignore: true) - PBGenerationViewData get managerData => currentContext.tree.data; + // @JsonKey(ignore: true) + // PBContext currentContext; - Map size; + // @JsonKey(ignore: true) + // PBGenerationViewData get managerData => currentContext.tree.data; /// Auxillary Data of the node. Contains properties such as BorderInfo, Alignment, Color & a directed graph of states relating to this element. @JsonKey(name: 'style') IntermediateAuxiliaryData auxiliaryData = IntermediateAuxiliaryData(); /// Name of the element if available. + @JsonKey(ignore: false) String name; PBIntermediateNode(this.UUID, this.frame, this.name, - {this.currentContext, this.subsemantic, this.constraints}) { + {this.subsemantic, this.constraints}) { logger = Logger(runtimeType.toString()); - _attributes = []; - _pointCorrection(); - } - - ///Correcting the pints when given the incorrect ones - void _pointCorrection() { - if (topLeftCorner != null && bottomRightCorner != null) { - if (topLeftCorner.x > bottomRightCorner.x && - topLeftCorner.y > bottomRightCorner.y) { - logger.warning( - 'Correcting the positional data. BTC is higher than TLC for node: ${this}'); - topLeftCorner = Point(min(topLeftCorner.x, bottomRightCorner.x), - min(topLeftCorner.y, bottomRightCorner.y)); - bottomRightCorner = Point(max(topLeftCorner.x, bottomRightCorner.x), - max(topLeftCorner.y, bottomRightCorner.y)); - } - } + // _attributes = []; } /// Returns the [PBAttribute] named `attributeName`. Returns /// null if the [PBAttribute] does not exist. - PBAttribute getAttributeNamed(String attributeName) { - for (var attribute in attributes) { - if (attribute.attributeName == attributeName) { - return attribute; - } + PBIntermediateNode getAttributeNamed(String attributeName) { + return children.firstWhere( + (element) => element.attributeName == attributeName, + orElse: () => null); + } + + List getAllAtrributeNamed(String attributeName) { + return children + .where((element) => element.attributeName == attributeName) + .toList(); + } + + void replaceAttribute(String attributeName, PBIntermediateNode node, + {bool allApperences = true}) { + if (hasAttribute(attributeName)) { + allApperences + ? children + .removeWhere((element) => element.attributeName == attributeName) + : children.remove(children + .firstWhere((element) => element.attributeName == attributeName)); + children.add(node); } - return null; } /// Returns true if there is an attribute in the node's `attributes` /// that matches `attributeName`. Returns false otherwise. bool hasAttribute(String attributeName) { - for (var attribute in attributes) { - if (attribute.attributeName == attributeName) { - return true; - } - } - return false; + return children.any((element) => element.attributeName == attributeName); } /// Adds the [PBAttribute] to this node's `attributes` list. /// When `overwrite` is set to true, if the provided `attribute` has the same /// name as another attribute in `attributes`, it will replace the old one. /// Returns true if the addition was successful, false otherwise. - bool addAttribute(PBAttribute attribute, {bool overwrite = false}) { - // Iterate through the list of attributes - for (var i = 0; i < attributes.length; i++) { - var childAttr = attributes[i]; - - // If there is a duplicate, replace if `overwrite` is true - if (childAttr.attributeName == attribute.attributeName) { - if (overwrite) { - attributes[i] = attribute; - return true; - } - return false; - } - } - - // Add attribute, no duplicate found - attributes.add(attribute); - return true; - } + // bool addAttribute(PBAttribute attribute, {bool overwrite = false}) { + // // Iterate through the list of attributes + // for (var i = 0; i < attributes.length; i++) { + // var childAttr = attributes[i]; + + // // If there is a duplicate, replace if `overwrite` is true + // if (childAttr.attributeName == attribute.attributeName) { + // if (overwrite) { + // attributes[i] = attribute; + // return true; + // } + // return false; + // } + // } + + // // Add attribute, no duplicate found + // attributes.add(attribute); + // return true; + // } /// Adds child to node. void addChild(PBIntermediateNode node) { @@ -184,6 +192,8 @@ abstract class PBIntermediateNode extends TraversableNode { /// constrains could be inherited to that section of the sub-tree. } + void handleChildren(PBContext context) {} + /// In a recursive manner align the current [this] and the [children] of [this] /// /// Its creating a [PBContext.clone] because some values of the [context] are modified @@ -196,7 +206,8 @@ abstract class PBIntermediateNode extends TraversableNode { /// INFO: there might be a more straight fowards backtracking way of preventing these side effects. void align(PBContext context) { alignStrategy.align(context, this); - for (var child in children) { + for (var att in children ?? []) { + var child = att.attributeNode; child?.align(context.clone()); } } @@ -206,13 +217,6 @@ abstract class PBIntermediateNode extends TraversableNode { Map toJson() => _$PBIntermediateNodeToJson(this); - static Map sizeFromJson(Map json) { - return { - 'width': json['width'], - 'height': json['height'], - }; - } - void mapRawChildren(Map json) { var rawChildren = json['children'] as List; rawChildren?.forEach((child) { @@ -221,6 +225,34 @@ abstract class PBIntermediateNode extends TraversableNode { } }); } + + // static List _childrenFromJson(Map json) { + // var key = 'children'; + // var children = json[key] as List; + // return [ + // PBAttribute(key, + // attributeNodes: children + // .map((child) => PBIntermediateNode.fromJson(child)) + // .toList()) + // ]; + // } + + // static Map _childrenToJson(List attributes) { + // var mapEntries = attributes + // .map((PBAttribute attribute) => MapEntry( + // attribute.attributeName, + // attribute.attributeNode == null + // ? attribute.attributeNodes.map((e) => e.toJson()).toList() + // : [attribute.attributeNode.toJson()])) + // .toList(); + // return Map.fromEntries(mapEntries); + // } + + // static PBAttribute _childToJson(Map json) { + // var key = 'child'; + // return PBAttribute(key, + // attributeNodes: [PBIntermediateNode.fromJson(json[key])]); + // } } extension PBPointLegacyMethod on Point { @@ -285,7 +317,7 @@ extension DeserializedRectangle on Rectangle { Point get bottomRightCorner => bottomRight; static Rectangle fromJson(Map json) { - return Rectangle(json['x'], json['y'], json['width'], json['height']); + return Rectangle(json['x'], json['y'], json['width'], json['height']); } static Map toJson(Rectangle rectangle) => { diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart index 65468eff..79905b06 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart @@ -10,12 +10,7 @@ Map _$PBIntermediateNodeToJson(PBIntermediateNode instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'topLeftCorner': PBPointLegacyMethod.toJson(instance.topLeftCorner), - 'bottomRightCorner': - PBPointLegacyMethod.toJson(instance.bottomRightCorner), - 'frame': DeserializedRectangle.toJson(instance.frame), - 'width': instance.width, - 'height': instance.height, + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, }; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index 384b99df..f4a62128 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -4,7 +4,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/exceptions/layout_exception.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; @@ -15,11 +14,6 @@ import 'package:uuid/uuid.dart'; /// Superclass: PBIntermediateNode abstract class PBLayoutIntermediateNode extends PBIntermediateNode implements PBInjectedIntermediate, PrototypeEnable { - ///Getting the children - @override - List get children => - getAttributeNamed('children')?.attributeNodes; - ///The rules of the layout. MAKE SURE TO REGISTER THEIR CUSTOM RULES final List _layoutRules; @@ -37,22 +31,15 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode Map alignment = {}; - PBLayoutIntermediateNode(String UUID, Rectangle frame, this._layoutRules, this._exceptions, - PBContext currentContext, String name, - { - this.prototypeNode, - PBIntermediateConstraints constraints}) - : super(UUID ?? Uuid().v4(), frame, name, - currentContext: currentContext, constraints: constraints) { - // Declaring children for layout node - addAttribute(PBAttribute('children')); - } + PBLayoutIntermediateNode(String UUID, Rectangle frame, this._layoutRules, + this._exceptions, String name, + {this.prototypeNode, PBIntermediateConstraints constraints}) + : super(UUID ?? Uuid().v4(), frame, name, constraints: constraints); ///Replace the current children with the [children] - void replaceChildren(List children) { + void replaceChildren(List children, PBContext context) { if (children.isNotEmpty) { - getAttributeNamed('children')?.attributeNodes = children; - resize(); + resize(context); } else { logger.warning( 'Trying to add a list of children to the $runtimeType that is either null or empty'); @@ -63,50 +50,61 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode /// Returns true if the replacement wsa succesful, false otherwise. bool replaceChildAt(int index, PBIntermediateNode replacement) { if (children != null && children.length > index) { - getAttributeNamed('children').attributeNodes[index] = replacement; + children[index] = replacement; return true; } return false; } - ///Add node to child - void addChildToLayout(PBIntermediateNode node) { - getAttributeNamed('children').attributeNodes.add(node); - resize(); + @override + void addChild(PBIntermediateNode node) { + super.addChild(node); } - void resize() { + @override + void handleChildren(PBContext context) { + resize(context); + super.handleChildren(context); + } + + ///Add node to child + // void addChildToLayout(PBIntermediateNode node) { + // getAttributeNamed('children').attributeNodes.add(node); + // resize(); + // } + + void resize(PBContext context) { if (children.isEmpty) { logger .warning('There should be children in the layout so it can resize.'); return; } - var minX = (children[0]).topLeftCorner.x, - minY = (children[0]).topLeftCorner.y, - maxX = (children[0]).bottomRightCorner.x, - maxY = (children[0]).bottomRightCorner.y; + var minX = (children[0]).frame.topLeft.x, + minY = (children[0]).frame.topLeft.y, + maxX = (children[0]).frame.bottomRight.x, + maxY = (children[0]).frame.bottomRight.y; for (var child in children) { - minX = min((child).topLeftCorner.x, minX); - minY = min((child).topLeftCorner.y, minY); - maxX = max((child).bottomRightCorner.x, maxX); - maxY = max((child).bottomRightCorner.y, maxY); + minX = min((child).frame.topLeft.x, minX); + minY = min((child).frame.topLeft.y, minY); + maxX = max((child).frame.bottomRight.x, maxX); + maxY = max((child).frame.bottomRight.y, maxY); } - topLeftCorner = Point(minX, minY); - bottomRightCorner = Point(maxX, maxY); + frame = Rectangle.fromPoints(Point(minX, minY), Point(maxX, maxY)); } ///Remove Child - bool removeChildren(PBIntermediateNode node) { + bool removeChildren(PBIntermediateNode node, PBContext context) { if (children.contains(node)) { children.remove(node); } - resize(); + resize(context); return false; } ///Sort children - void sortChildren() => children.sort( - (child0, child1) => child0.topLeftCorner.compareTo(child1.topLeftCorner)); + void sortChildren() => + children.sort((child0, child1) => child0.frame.topLeft + .compareTo(child1.frame.topLeft)); ///The [PBLayoutIntermediateNode] contains a series of rules that determines if the children is part of that layout. All the children ///are going to have to meet the rules that the [PBLayoutIntermediateNode] presents. This method presents a way of comparing two children [PBIntermediateNode] @@ -133,43 +131,43 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode List children, PBContext currentContext, String name); void checkCrossAxisAlignment() { - if (attributes.first.attributeNode != null) { - var attributesTopLeft = attributes.first.attributeNode.topLeftCorner; - - var attributesBottomRight = - attributes.last.attributeNode.bottomRightCorner; - - var leftDifference = (topLeftCorner.x - attributesTopLeft.x).abs(); - - var rightDifference = - (bottomRightCorner.x - attributesBottomRight.x).abs(); - - var topDifference = (topLeftCorner.y - attributesTopLeft.y).abs(); - - var bottomDifference = - (bottomRightCorner.y - attributesBottomRight.y).abs(); - - if (leftDifference < rightDifference) { - alignment['mainAxisAlignment'] = - 'mainAxisAlignment: MainAxisAlignment.start,'; - } else if (leftDifference > rightDifference) { - alignment['mainAxisAlignment'] = - 'mainAxisAlignment: MainAxisAlignment.end,'; - } else { - alignment['mainAxisAlignment'] = - 'mainAxisAlignment: MainAxisAlignment.center,'; - } - - if (topDifference < bottomDifference) { - alignment['crossAxisAlignment'] = - 'crossAxisAlignment: CrossAxisAlignment.start,'; - } else if (topDifference > bottomDifference) { - alignment['crossAxisAlignment'] = - 'crossAxisAlignment: CrossAxisAlignment.end,'; - } else { - alignment['crossAxisAlignment'] = - 'crossAxisAlignment: CrossAxisAlignment.center,'; - } - } + // if (attributes.first.attributeNode != null) { + // var attributesTopLeft = attributes.first.attributeNode.frame.topLeft; + + // var attributesBottomRight = + // attributes.last.attributeNode.frame.bottomRight; + + // var leftDifference = (frame.topLeft.x - attributesTopLeft.x).abs(); + + // var rightDifference = + // (frame.bottomRight.x - attributesBottomRight.x).abs(); + + // var topDifference = (frame.topLeft.y - attributesTopLeft.y).abs(); + + // var bottomDifference = + // (frame.bottomRight.y - attributesBottomRight.y).abs(); + + // if (leftDifference < rightDifference) { + // alignment['mainAxisAlignment'] = + // 'mainAxisAlignment: MainAxisAlignment.start,'; + // } else if (leftDifference > rightDifference) { + // alignment['mainAxisAlignment'] = + // 'mainAxisAlignment: MainAxisAlignment.end,'; + // } else { + // alignment['mainAxisAlignment'] = + // 'mainAxisAlignment: MainAxisAlignment.center,'; + // } + + // if (topDifference < bottomDifference) { + // alignment['crossAxisAlignment'] = + // 'crossAxisAlignment: CrossAxisAlignment.start,'; + // } else if (topDifference > bottomDifference) { + // alignment['crossAxisAlignment'] = + // 'crossAxisAlignment: CrossAxisAlignment.end,'; + // } else { + // alignment['crossAxisAlignment'] = + // 'crossAxisAlignment: CrossAxisAlignment.center,'; + // } + // } } } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart index f231d841..eb2e66cf 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart @@ -9,10 +9,8 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; /// Represents a typical node that the end-user could see, it usually has properties such as size and color. It only contains a single child, unlike PBLayoutIntermediateNode that contains a set of children. /// Superclass: PBIntermediateNode abstract class PBVisualIntermediateNode extends PBIntermediateNode { - PBVisualIntermediateNode( - String UUID, Rectangle rectangle, PBContext currentContext, String name, + String UUID, Rectangle rectangle, String name, {PBIntermediateConstraints constraints}) - : super(UUID, rectangle, name, - currentContext: currentContext, constraints: constraints); + : super(UUID, rectangle, name, constraints: constraints); } diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index f9e87070..022a3542 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -26,7 +26,7 @@ class AbstractIntermediateNodeFactory { InheritedContainer('$InheritedContainer', null), InheritedOval('$InheritedOval', null), InheritedPolygon('$InheritedPolygon', null), - InheritedScaffold('$InheritedScaffold', null), + InheritedScaffold('$InheritedScaffold', null, null, null), InheritedShapeGroup('$InheritedShapeGroup', null), InheritedShapePath('$InheritedShapePath', null), InheritedStar('$InheritedStar', null), diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 01de98f0..cbc09a40 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -44,16 +44,18 @@ abstract class AlignStrategy { class PaddingAlignment extends AlignStrategy { @override void align(PBContext context, PBIntermediateNode node) { - var padding = Padding(null, node.frame, node.child.constraints, - left: (node.child.topLeftCorner.x - node.topLeftCorner.x).abs(), - right: - (node.bottomRightCorner.x - node.child.bottomRightCorner.x).abs(), - top: (node.child.topLeftCorner.y - node.topLeftCorner.y).abs(), - bottom: - (node.child.bottomRightCorner.y - node.bottomRightCorner.y).abs(), - currentContext: node.currentContext); - padding.addChild(node.child); - node.child = padding; + var child = node.getAttributeNamed('child'); + var padding = Padding( + null, + node.frame, + child.constraints, + left: (child.frame.topLeft.x - node.frame.topLeft.x).abs(), + right: (node.frame.bottomRight.x - child.frame.bottomRight.x).abs(), + top: (child.frame.topLeft.y - node.frame.topLeft.y).abs(), + bottom: (child.frame.bottomRight.y - node.frame.bottomRight.y).abs(), + ); + padding.addChild(child); + node.addChild(padding); super._setConstraints(context, node); } } @@ -66,34 +68,35 @@ class NoAlignment extends AlignStrategy { } class PositionedAlignment extends AlignStrategy { - /// Do we need to subtract some sort of offset? Maybe child.topLeftCorner.x - topLeftCorner.x? + /// Do we need to subtract some sort of offset? Maybe child .frame.topLeft.x - topLeftCorner.x? @override void align(PBContext context, PBIntermediateStackLayout node) { var alignedChildren = []; - node.children.skipWhile((child) { + node.children.skipWhile((att) { + var child = att; + /// if they are the same size then there is no need for adjusting. - if (child.topLeftCorner == node.topLeftCorner && - child.bottomRightCorner == node.bottomRightCorner) { + if (child.frame.topLeft == node.frame.topLeft && + child.frame.bottomRight == node.frame.bottomRight) { alignedChildren.add(child); return true; } return false; - }).forEach((child) { - alignedChildren.add(InjectedPositioned(null, - child.frame, + }).forEach((att) { + var child = att; + alignedChildren.add(InjectedPositioned(null, child.frame, constraints: child.constraints, - currentContext: context, valueHolder: PositionedValueHolder( - top: child.topLeftCorner.y - node.topLeftCorner.y, - bottom: node.bottomRightCorner.y - child.bottomRightCorner.y, - left: child.topLeftCorner.x - node.topLeftCorner.x, - right: node.bottomRightCorner.x - child.bottomRightCorner.x, - width: child.width, - height: child.height)) + top: child.frame.topLeft.y - node.frame.topLeft.y, + bottom: node.frame.bottomRight.y - child.frame.bottomRight.y, + left: child.frame.topLeft.x - node.frame.topLeft.x, + right: node.frame.bottomRight.x - child.frame.bottomRight.x, + width: child.frame.width, + height: child.frame.height)) ..addChild(child)); }); - node.replaceChildren(alignedChildren); + node.replaceChildren(alignedChildren, context); super._setConstraints(context, node); } } diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 17ef14d6..81bdeb42 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -4,7 +4,6 @@ import 'package:quick_log/quick_log.dart'; abstract class ChildrenStrategy { Logger log; - //TODO: will be used in the migrations to attributes final String attributeName; final bool overwridable; ChildrenStrategy(this.attributeName, this.overwridable) { @@ -21,7 +20,7 @@ class OneChildStrategy extends ChildrenStrategy { void addChild(PBIntermediateNode target, dynamic child) { if (child is PBIntermediateNode) { child.parent = target; - target.child = child; + target.children = [child]; } else { log.warning( 'Tried adding ${child.runtimeType.toString()} to ${target.runtimeType.toString()}'); @@ -36,12 +35,13 @@ class MultipleChildStrategy extends ChildrenStrategy { @override void addChild(PBIntermediateNode target, children) { if (children is List) { - children.forEach((child) { + target.children.addAll(children.map((child) { child.parent = target; - target.children.add(child); - }); + return child; + })); } else if (children is PBIntermediateNode) { - target.child = children; + children.parent = target; + children.forEach(target.addChild); } } } @@ -64,18 +64,20 @@ class TempChildrenStrategy extends ChildrenStrategy { @override void addChild(PBIntermediateNode target, children) { - if (target.child is TempGroupLayoutNode) { - target.child.addChild(children); - } else if (target.child != null) { - var temp = TempGroupLayoutNode(null, null, - currentContext: target.currentContext, name: children.name); - temp.addChild(target.child); - temp.addChild(children); - temp.parent = target; - target.child = temp; + var group = + target.children.firstWhere((element) => element is TempGroupLayoutNode); + if (group != null && target.children.length == 1) { + group.addChild(children); + } else if (target.children.isNotEmpty) { + var child = target.children.first; + var temp = TempGroupLayoutNode(null, null, name: children.name) + ..addChild(child) + ..addChild(children) + ..parent = target; + target.children = [temp]; } else if (children is PBIntermediateNode) { children.parent = target; - target.child = children; + target.addChild(children); } } } diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index b5bf2f92..92cbee24 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -10,27 +10,13 @@ import 'dart:math'; class PBContext { final PBConfiguration configuration; - /// These are the original screen mesurements comming from the design values. - Point _screenTLC; - Point get screenTopLeftCorner => _screenTLC; - set screenTopLeftCorner(Point screenTopLeftCorner) { - if (_screenTLC == null) { - canvasTLC = screenTopLeftCorner; - } - _screenTLC = screenTopLeftCorner; - } - - Point _screenBRC; - Point get screenBottomRightCorner => _screenBRC; - set screenBottomRightCorner(Point screenBottomRightCorner) { - if (_screenBRC == null) { - canvasBRC = screenBottomRightCorner; - } - _screenBRC = screenBottomRightCorner; + Rectangle _screenFrame; + Rectangle get screenFrame => _screenFrame; + set screenFrame(Rectangle frame){ + canvasFrame ??= Rectangle.fromPoints(frame.topLeft, frame.bottomRight); + _screenFrame = frame; } - double get originalScreenWidth => _screenBRC.x - _screenTLC.x; - double get originaScreenHeight => _screenBRC.y - _screenTLC.y; /// These values represent the current "focus area" size as it travels down the /// tree. @@ -40,8 +26,7 @@ class PBContext { /// Some of the scenarios the focusAreaWould change: /// - When the appbar is used, it should shrink the canvas top point to make room for the appbar /// - When another stack is declared, its TLC becomes the new canvas TLC(same for BRC). - Point canvasTLC; - Point canvasBRC; + Rectangle canvasFrame; /// The [constextConstrains] represents the costraints that would be inherited by a section of the tree. /// @@ -64,8 +49,7 @@ class PBContext { this.contextConstraints, this.masterNode, this.project, - this.canvasBRC, - this.canvasTLC, + this.canvasFrame, this.generationManager}) { contextConstraints ??= PBIntermediateConstraints(); } @@ -86,8 +70,8 @@ class PBContext { return size; } return isHorizontal - ? size / originalScreenWidth - : size / originaScreenHeight; + ? size / screenFrame.width + : size / screenFrame.height; } PBContext clone() { @@ -96,11 +80,9 @@ class PBContext { contextConstraints: contextConstraints.clone(), masterNode: masterNode, project: project, - canvasBRC: canvasBRC, - canvasTLC: canvasTLC, + canvasFrame: canvasFrame, generationManager: generationManager); - context.screenTopLeftCorner = _screenTLC; - context.screenBottomRightCorner = _screenBRC; + context.screenFrame = _screenFrame; return context; } } diff --git a/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart b/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart index df24074e..0ec9225e 100644 --- a/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart +++ b/lib/interpret_and_optimize/helpers/pb_image_reference_storage.dart @@ -25,6 +25,9 @@ class ImageReferenceStorage { /// Adds the reference to the image and writes the png to the assets folder. /// Returns true if the image was written successfully, false otherwise bool addReferenceAndWrite(String name, String path, Uint8List image) { + if(image == null){ + return false; + } var imgPath = p.join(MainInfo().pngPath, '$name.png'); if (image == null && File('${MainInfo().cwd?.path}/lib/input/assets/image-conversion-error.png') diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart index 30e68d3a..2fb1f4d9 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart @@ -6,7 +6,6 @@ class IntermediateDFSIterator final PBIntermediateTree _tree; E _currentElement; - E get currentElement => _currentElement; List _stack; diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart new file mode 100644 index 00000000..bd094ce0 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart @@ -0,0 +1,32 @@ +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + +class IntermediateLayerIterator + implements Iterator> { + final PBIntermediateTree _tree; + List> _stack; + + @override + List get current => _current; + List _current; + + @override + bool moveNext() { + if (_stack.isNotEmpty) { + _current = _stack.removeAt(0); + _stack.add(_current + .expand((element) => element.children as Iterable)); + return true; + } + return false; + } + + IntermediateLayerIterator(this._tree, {E starting}) { + var initNode = starting ?? _tree.rootNode; + if (initNode == null) { + throw NullThrownError(); + } + _stack = [ + [initNode] + ]; + } +} diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 7819bce0..5b1ec117 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -3,7 +3,9 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart'; import 'package:recase/recase.dart'; import 'package:tuple/tuple.dart'; import "dart:collection"; @@ -24,6 +26,8 @@ class PBIntermediateTree extends Iterable String _UUID; String get UUID => _UUID; + PBContext context; + /// The [TREE_TYPE] of the [PBIntermediateTree]. @JsonKey(ignore: true) TREE_TYPE tree_type = TREE_TYPE.SCREEN; @@ -94,9 +98,7 @@ class PBIntermediateTree extends Iterable @JsonKey(name: 'name') String get identifier => _identifier?.snakeCase ?? 'no_name_found'; - PBIntermediateTree({ - String name, - }) { + PBIntermediateTree({String name, this.context}) { _name = name; _dependentsOn = {}; _UUID = Uuid().v4(); @@ -118,7 +120,6 @@ class PBIntermediateTree extends Iterable bool isHomeScreen() => isScreen() && (rootNode as InheritedScaffold).isHomeScreen; - /// Finding the depth of the [node] in relation to the [rootNode]. int depthOf(node) { return dist(rootNode, node); @@ -126,10 +127,10 @@ class PBIntermediateTree extends Iterable /// Find the distance between [source] and [target], where the [source] is an /// ancestor of [target]. - /// - /// IF [source] IS NOT AN ANCESTOR OF [target] OR [target] IS + /// + /// IF [source] IS NOT AN ANCESTOR OF [target] OR [target] IS /// NOT PRESENT IN THE [PBIntermediateNode], THEN ITS GOING TO RETURN `-1`. - /// This is because the nodes of the tree dont have an out going edge + /// This is because the nodes of the tree dont have an out going edge /// pointing towards its parents, all directed edges are going down the tree. int dist(PBIntermediateNode source, PBIntermediateNode target, {int edgeCost = 1}) { @@ -162,7 +163,7 @@ class PBIntermediateTree extends Iterable } /// returning the found [target] distance. - if(outNode == target){ + if (outNode == target) { return dist[target]; } } @@ -173,6 +174,9 @@ class PBIntermediateTree extends Iterable @override Iterator get iterator => IntermediateDFSIterator(this); + Iterator get layerIterator => + IntermediateLayerIterator(this); + Map toJson() => _$PBIntermediateTreeToJson(this); static PBIntermediateTree fromJson(Map json) => @@ -191,8 +195,8 @@ class PBIntermediateTree extends Iterable /// children by using the [IntermediateDFSIterator]. Furthermore, this allows the /// [PBIntermediateTree] to traverse through its nodes, leveraging the dart methods. abstract class TraversableNode { + String attributeName; E parent; - int treeLevel; List children; } diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index 40c0f6de..8bef57cd 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -13,13 +13,12 @@ class PBPluginListHelper { static final PBPluginListHelper _instance = PBPluginListHelper._internal(); void initPlugins(PBContext context) { allowListNames = { - '': InjectedTabBar(null, null, '', currentContext: context), - '': InjectedAppbar(null, null, '', currentContext: context), + '': InjectedTabBar(null, null, ''), + '': InjectedAppbar(null, null, ''), '': Tab( null, null, '', - currentContext: context, ), '': CustomEgg(null, null, ''), }; diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 4f227ab6..ab3dcb96 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -7,7 +7,6 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.d import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_visual_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_state.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_variation.dart'; diff --git a/lib/interpret_and_optimize/services/intermediate_node_searcher_service.dart b/lib/interpret_and_optimize/services/intermediate_node_searcher_service.dart index 21e22f71..345ec5f5 100644 --- a/lib/interpret_and_optimize/services/intermediate_node_searcher_service.dart +++ b/lib/interpret_and_optimize/services/intermediate_node_searcher_service.dart @@ -56,37 +56,36 @@ class PBIntermediateNodeSearcherService { while (stack.isNotEmpty) { var currentNode = stack.removeLast(); if (currentNode is InheritedScaffold) { - var tabbar = - currentNode.getAttributeNamed('bottomNavigationBar')?.attributeNode; - var tabs = tabbar?.getAttributeNamed('tabs')?.attributeNodes; - if (tabbar != null && tabs?.isNotEmpty ?? false) { + var tabbar = currentNode.getAttributeNamed('bottomNavigationBar'); + var tabs = tabbar?.getAllAtrributeNamed('tabs'); + if (tabbar != null && tabs.isNotEmpty ?? false) { for (var i = 0; i < tabs.length; i++) { var child = tabs[i]; if (child.UUID == uuid) { - tabs[i].child = candidate; + // tabs[i].child = candidate; return true; } - stack.add(child); + // stack.add(child); } } } - if (currentNode is PBLayoutIntermediateNode) { - for (var i = 0; i < currentNode.children.length; i++) { - var child = currentNode.children[i]; - if (child.UUID == uuid) { - currentNode.replaceChildAt(i, candidate); - return true; - } - stack.add(child); - } - } else if (currentNode is PBVisualIntermediateNode && - currentNode.child != null) { - if (currentNode.child.UUID == uuid) { - currentNode.child = candidate; - return true; - } - stack.add(currentNode.child); - } + // if (currentNode is PBLayoutIntermediateNode) { + // for (var i = 0; i < currentNode.children.length; i++) { + // var child = currentNode.children[i]; + // if (child.UUID == uuid) { + // currentNode.replaceChildAt(i, candidate); + // return true; + // } + // stack.add(child); + // } + // } else if (currentNode is PBVisualIntermediateNode && + // currentNode.child != null) { + // if (currentNode.child.UUID == uuid) { + // currentNode.child = candidate; + // return true; + // } + // stack.add(currentNode.child); + // } } return false; } diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 4a9cc52c..dd7b7de9 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -6,7 +6,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layo import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_attribute.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; @@ -44,9 +43,7 @@ class PBLayoutGenerationService extends AITHandler { // ), // 'row': PBIntermediateRowLayout('', Uuid().v4(), // currentContext: currentContext), - 'stack': PBIntermediateStackLayout( - null, - ), + 'stack': PBIntermediateStackLayout(), }; for (var layoutType @@ -67,27 +64,33 @@ class PBLayoutGenerationService extends AITHandler { return Future.value(tree); } try { - // rootNode = (tree - // .map(_removingMeaninglessGroup) - // .map((node) => _layoutConditionalReplacement(node, context)) - // .toList() - // ..removeWhere((element) => element == null)) - // .first; - rootNode = _traverseLayersUtil(rootNode, (layer) { - return layer + var removedList = tree.toList() + ..removeWhere((node) => node is TempGroupLayoutNode); + tree.rootNode = removedList.first; + // tree.forEach((att) => _removingMeaninglessGroup(att.attributeNode)); + rootNode = (tree + .map((node) => _removingMeaninglessGroup(node)) + .map((node) => _transformGroup(node)) + .map((node) => _layoutConditionalReplacement(node, context)) + .toList() + ..removeWhere((element) => element == null)) + .first; + // rootNode = _traverseLayersUtil(rootNode, (layer) { + // return layer + /// [rootNode -> scaffold], [scaffold, container], [temp, bitmap], [container, bitmap] - ///Remove the `TempGroupLayout` nodes that only contain one node - .map(_removingMeaninglessGroup) - .map((node) => _layoutConditionalReplacement(node, context)) - .toList() + // ///Remove the `TempGroupLayout` nodes that only contain one node + // .map(_removingMeaninglessGroup) + // .map((node) => _layoutConditionalReplacement(node, context)) + // .toList() - /// Filter out the elements that are null in the tree - ..removeWhere((element) => element == null); - }); + // /// Filter out the elements that are null in the tree + // ..removeWhere((element) => element == null); + // }); ///After all the layouts are generated, the [PostConditionRules] are going ///to be applyed to the layerss - _applyPostConditionRules(rootNode); + _applyPostConditionRules(rootNode, context); // return Future.value(tree); } catch (e, stackTrace) { MainInfo().sentry.captureException( @@ -101,45 +104,45 @@ class PBLayoutGenerationService extends AITHandler { } } - PBIntermediateNode _traverseLayersUtil( - PBIntermediateNode rootNode, - List Function(List layer) - transformation) { - ///The stack is going to saving the current layer of tree along with the parent of - ///the layer. It makes use of a `Tuple2()` to save the parent in the first index and a list - ///of nodes for the current layer in the second layer. - var stack = >>[]; - stack.add(Tuple2(null, [ - PBAttribute('root', attributeNodes: [rootNode]) - ])); + // PBIntermediateNode _traverseLayersUtil( + // PBIntermediateNode rootNode, + // List Function(List layer) + // transformation) { + // ///The stack is going to saving the current layer of tree along with the parent of + // ///the layer. It makes use of a `Tuple2()` to save the parent in the first index and a list + // ///of nodes for the current layer in the second layer. + // var stack = >>[]; + // stack.add(Tuple2(null, [ + // PBAttribute('root', attributeNodes: [rootNode]) + // ])); - while (stack.isNotEmpty) { - var currentTuple = stack.removeLast(); - currentTuple.item2.forEach((currentAttribute) { - currentAttribute.attributeNodes = - transformation(currentAttribute.attributeNodes); - currentAttribute?.attributeNodes?.forEach((currentNode) { - currentNode?.attributes?.forEach((attribute) { - stack.add(Tuple2(currentNode, [ - PBAttribute(attribute.attributeName, - attributeNodes: attribute.attributeNodes) - ])); - }); - }); - }); - var node = currentTuple.item1; - if (node != null) { - currentTuple.item2.forEach((attribute) { - node.addAttribute(attribute, overwrite: true); - }); - } else { - ///if the `currentTuple.item1` is null, that implies the `currentTuple.item2.first` is the - ///new `rootNode`. - rootNode = currentTuple.item2.first.attributeNode; - } - } - return rootNode; - } + // while (stack.isNotEmpty) { + // var currentTuple = stack.removeLast(); + // currentTuple.item2.forEach((currentAttribute) { + // currentAttribute.attributeNodes = + // transformation(currentAttribute.attributeNodes); + // currentAttribute?.attributeNodes?.forEach((currentNode) { + // currentNode?.attributes?.forEach((attribute) { + // stack.add(Tuple2(currentNode, [ + // PBAttribute(attribute.attributeName, + // attributeNodes: attribute.attributeNodes) + // ])); + // }); + // }); + // }); + // var node = currentTuple.item1; + // if (node != null) { + // currentTuple.item2.forEach((attribute) { + // node.addAttribute(attribute, overwrite: true); + // }); + // } else { + // ///if the `currentTuple.item1` is null, that implies the `currentTuple.item2.first` is the + // ///new `rootNode`. + // rootNode = currentTuple.item2.first.attributeNode; + // } + // } + // return rootNode; + // } /// If this node is an unecessary [TempGroupLayoutNode], just return the child or an /// [InjectContainer] if the group is empty @@ -161,6 +164,17 @@ class PBLayoutGenerationService extends AITHandler { return tempGroup; } + /// Transforming the [TempGroupLayoutNode] into regular [PBLayoutIntermediateNode] + PBIntermediateNode _transformGroup(PBIntermediateNode group) { + if (group is TempGroupLayoutNode) { + var stack = PBIntermediateStackLayout( + name: group.name, constraints: group.constraints); + stack.children.addAll(group.children); + group = stack; + } + return group; + } + ///If `node` contains a single or multiple [PBIntermediateNode]s bool _containsChildren(PBIntermediateNode node) => (node is PBVisualIntermediateNode && node.child != null) || @@ -220,7 +234,7 @@ class PBLayoutGenerationService extends AITHandler { childPointer = reCheck ? 0 : childPointer + 1; reCheck = false; } - parent.replaceChildren(children); + parent.replaceChildren(children, context); if (children.length == 1) { /// With the support for scaling & pinning, Stacks are now responsible for positioning. if (parent is PBIntermediateStackLayout) { @@ -263,15 +277,19 @@ class PBLayoutGenerationService extends AITHandler { } ///Applying [PostConditionRule]s at the end of the [PBLayoutIntermediateNode] - PBIntermediateNode _applyPostConditionRules(PBIntermediateNode node) { + PBIntermediateNode _applyPostConditionRules( + PBIntermediateNode node, PBContext context) { if (node == null) { return node; } if (node is PBLayoutIntermediateNode && node.children.isNotEmpty) { node.replaceChildren( - node.children.map((node) => _applyPostConditionRules(node)).toList()); + node.children + .map((node) => _applyPostConditionRules(node, context)) + .toList(), + context); } else if (node is PBVisualIntermediateNode) { - node.child = _applyPostConditionRules(node.child); + node.children.map((e) => _applyPostConditionRules(e, context)); } for (var postConditionRule in _postLayoutRules) { diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 9991edad..ad869626 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -1,4 +1,5 @@ import 'dart:collection'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:recase/recase.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart'; @@ -30,11 +31,11 @@ class PBPlatformOrientationLinkerService { /// Populates [tree]'s platform and orientation information /// and adds [tree] to storage. - void addOrientationPlatformInformation(PBIntermediateTree tree) { + void addOrientationPlatformInformation(PBIntermediateTree tree, PBContext context) { tree.data.platform = _extractPlatform(tree.name); tree.data.orientation = _extractOrientation( - tree.rootNode.bottomRightCorner, - tree.rootNode.topLeftCorner, + tree.rootNode .frame.bottomRight, + tree.rootNode .frame.topLeft, ); _platforms.add(tree.data.platform); @@ -43,17 +44,17 @@ class PBPlatformOrientationLinkerService { // Add orientation builder template to the project // if there are more than 1 orientation on the project if (hasMultipleOrientations()) { - tree.rootNode.currentContext.configuration.generationConfiguration + context.configuration.generationConfiguration .commandQueue .add(OrientationBuilderCommand(tree.UUID)); } // Add responsive layout builder template to the project // if there are more than 1 plataform on the project if (hasMultiplePlatforms()) { - tree.rootNode.currentContext.configuration.generationConfiguration + context.configuration.generationConfiguration .commandQueue .add(ResponsiveLayoutBuilderCommand(tree.UUID)); - _addBreakpoints(tree); + _addBreakpoints(tree, context); } addToMap(tree); @@ -210,13 +211,13 @@ class PBPlatformOrientationLinkerService { return ORIENTATION.VERTICAL; } - void _addBreakpoints(PBIntermediateTree tree) { + void _addBreakpoints(PBIntermediateTree tree, PBContext context) { if (MainInfo().configuration.breakpoints != null) { var bp = MainInfo().configuration.breakpoints.cast(); bp.forEach((key, value) { var cmd = AddConstantCommand( tree.UUID, key + 'Breakpoint', 'num', value.toString()); - tree.rootNode.currentContext.configuration.generationConfiguration + context.configuration.generationConfiguration .commandQueue .add(cmd); }); diff --git a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart index 8009a36f..c0e9b526 100644 --- a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart +++ b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart @@ -22,11 +22,9 @@ class PBPluginControlService extends AITHandler { PBIntermediateTree tree, PBContext context) { var originalRoot = tree.rootNode; if (originalRoot == null) { - logger.warning( - 'generate() attempted to generate a non-existing tree.'); + logger.warning('generate() attempted to generate a non-existing tree.'); return null; } - var queue = []; PBIntermediateNode rootIntermediateNode; queue.add(LayerTuple([originalRoot], null)); @@ -54,18 +52,19 @@ class PBPluginControlService extends AITHandler { if (currentLayer.parent is PBVisualIntermediateNode) { assert(currentLayer.nodeLayer.length <= 1, '[Plugin Control Service] We are going to end up deleting nodes here, something probably went wrong.'); - (currentLayer.parent as PBVisualIntermediateNode).child = - currentLayer.nodeLayer[0]; + (currentLayer.parent as PBVisualIntermediateNode).replaceAttribute( + currentLayer.parent.first.attributeName, + currentLayer.nodeLayer[0]); } else if (currentLayer.parent is PBLayoutIntermediateNode) { (currentLayer.parent as PBLayoutIntermediateNode) - .replaceChildren(currentLayer.nodeLayer); + .replaceChildren(currentLayer.nodeLayer, context); } /// Add next depth layer to queue. if (currentIntermediateNode is PBVisualIntermediateNode && currentIntermediateNode.child != null) { - queue.add(LayerTuple( - [currentIntermediateNode.child], currentIntermediateNode)); + queue.add(LayerTuple([currentIntermediateNode.child], + currentIntermediateNode)); } else if (currentIntermediateNode is PBLayoutIntermediateNode && currentIntermediateNode.children != null) { queue.add(LayerTuple( diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index bd3c49d3..09a104f7 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -4,9 +4,10 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_n import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/intermediate_node_searcher_service.dart'; import 'package:quick_log/quick_log.dart'; +import 'intermediate_node_searcher_service.dart'; + class PBSharedInterAggregationService { PBSymbolStorage _symbolStorage; @@ -56,7 +57,7 @@ class PBSharedInterAggregationService { log.warning('UUID: $targetUUID not found in searchNodeByUUID'); } if ((prop.value != null) && (prop.type == 'symbolID')) { - prop.value.currentContext = rootChildNode.currentContext; + // prop.value.currentContext = rootChildNode.currentContext; ///if the [PBSharedMasterNode] contains [PBSharedInstanceIntermediateNode] as parameters ///then its going gather the information of its [PBSharedMasterNode]. @@ -94,8 +95,8 @@ class PBSharedInterAggregationService { return; } if (masterNode?.SYMBOL_ID == instanceIntermediateNode?.SYMBOL_ID) { - instanceIntermediateNode.currentContext - .addDependent(masterNode.currentContext.tree); + // instanceIntermediateNode.currentContext + // .addDependent(masterNode.currentContext.tree); ///Get the attributes of the [masterNode] to the [instanceIntermediateNode] here ([instanceIntermediateNode] attributes) instanceIntermediateNode.functionCallName = masterNode.name; diff --git a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart index 16b86eab..6564af75 100644 --- a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart @@ -9,7 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_shared_aggregation_service.dart'; -class PBSymbolLinkerService extends AITHandler{ +class PBSymbolLinkerService extends AITHandler { PBSymbolStorage _symbolStorage; PBSharedInterAggregationService _aggregationService; @@ -20,43 +20,28 @@ class PBSymbolLinkerService extends AITHandler{ // /Linking [PBSharedMasterNode] and [PBSharedInstanceIntermediateNode] together; linking its // /parameter and values. - Future linkSymbols(PBIntermediateTree tree) async{ + Future linkSymbols(PBIntermediateTree tree) async { var rootNode = tree.rootNode; - if(rootNode == null){ + if (rootNode == null) { return Future.value(tree); } - var stack = []; - PBIntermediateNode rootIntermediateNode; - stack.add(rootNode); - - while (stack.isNotEmpty) { - var currentNode = stack.removeLast(); - // Traverse `currentNode's` attributes and add to stack - currentNode.attributes.forEach((attribute) { - attribute.attributeNodes.forEach((node) { - node.currentContext ??= currentNode.currentContext; - stack.add(node); - }); - }); - - if (currentNode is PBSharedMasterNode) { - await _symbolStorage.addSharedMasterNode(currentNode); - _aggregationService.gatherSharedParameters( - currentNode, currentNode.child); - } else if (currentNode is PBSharedInstanceIntermediateNode) { - await _symbolStorage.addSharedInstance(currentNode); - _aggregationService.gatherSharedValues(currentNode); + for (PBIntermediateNode node in tree) { + if (node is PBSharedMasterNode) { + await _symbolStorage.addSharedMasterNode(node); + _aggregationService.gatherSharedParameters(node, node.child); + } else if (node is PBSharedInstanceIntermediateNode) { + await _symbolStorage.addSharedInstance(node); + _aggregationService.gatherSharedValues(node); } - - rootIntermediateNode ??= currentNode; } - tree.rootNode = rootIntermediateNode; + return Future.value(tree); } @override - Future handleTree(PBContext context, PBIntermediateTree tree) { + Future handleTree( + PBContext context, PBIntermediateTree tree) { return linkSymbols(tree); } } diff --git a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart b/lib/interpret_and_optimize/services/pb_visual_generation_service.dart deleted file mode 100644 index 277cf89f..00000000 --- a/lib/interpret_and_optimize/services/pb_visual_generation_service.dart +++ /dev/null @@ -1,153 +0,0 @@ -// import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; -// import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -// import 'package:parabeac_core/interpret_and_optimize/entities/pb_deny_list_node.dart'; -// import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; -// import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_deny_list_helper.dart'; -// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; -// import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; -// import 'package:parabeac_core/interpret_and_optimize/services/pb_generation_service.dart'; - -// /// Takes a SketchNodeTree and begins generating PBNode interpretations. For each node, the node is going to pass through the PBSemanticInterpretationService which checks if the node should generate a specific PBIntermediateNode based on the semantics that it contains. -// /// Input: SketchNodeTree -// /// Output: PBIntermediateNodeTree -// class PBVisualGenerationService implements PBGenerationService { - -// @override -// PBContext currentContext; - -// PBStateManagementHelper smHelper; - -// PBIntermediateNode originalRoot; - -// /// Boolean that is `true` if the [VisualGenerationService] -// /// is currently processing a state management node -// bool _ignoreStates; - -// /// Constructor for PBVisualGenerationService, must include the root SketchNode -// PBVisualGenerationService(originalRoot, -// {this.currentContext, bool ignoreStates = false}) { -// _ignoreStates = ignoreStates; -// // Only do positional cleansing for non-state nodes, since those nodes -// // have already been through this service -// // if (!_ignoreStates) { -// // _positionalCleansingService = PositionalCleansingService(); -// // this.originalRoot = -// // _positionalCleansingService.eliminateOffset(originalRoot); -// // } else { -// // this.originalRoot = originalRoot; -// // } - -// smHelper = PBStateManagementHelper(); -// } - -// /// Builds and returns intermediate tree by breadth depth first. -// /// @return Returns the root node of the intermediate tree. -// Future getIntermediateTree() async { -// if (originalRoot == null) { -// return Future.value(null); -// } -// PBPluginListHelper().initPlugins(currentContext); - -// var queue = []; -// PBIntermediateNode rootIntermediateNode; -// queue.add(NodeTuple(originalRoot, null)); -// while (queue.isNotEmpty) { -// var currentNode = queue.removeAt(0); - -// if (currentNode.designNode?.isVisible ?? true) { -// PBIntermediateNode result; -// // Check semantics -// result = PBDenyListHelper() -// .returnDenyListNodeIfExist(currentNode.designNode); - -// if (result is PBDenyListNode) { -// } else { -// result = PBPluginListHelper() -// .returnAllowListNodeIfExists(currentNode.designNode); - -// /// Generate general intermediate node if still null. -// /// needs to be assigned to [original], because [symbolMaster] needs to be registered to SymbolMaster - -// if (result == null || -// currentNode.designNode is PBSharedInstanceDesignNode || -// currentNode.designNode is PBSharedMasterDesignNode) { -// result = await currentNode.designNode.interpretNode(currentContext); -// } - -// // Interpret state management node -// if (!_ignoreStates && -// smHelper.isValidStateNode(result.name) && -// (currentNode.designNode.name != -// currentNode.convertedParent?.name ?? -// true) && -// result is PBSharedMasterNode) { -// if (smHelper.isDefaultNode(result)) { -// smHelper.interpretStateManagementNode(result); -// } else { -// smHelper.interpretStateManagementNode(result); -// continue; -// } -// } - -// if (currentNode.convertedParent != null) { -// _addToParent(currentNode.convertedParent, result); -// } - -// // If we haven't assigned the rootIntermediateNode, this must be the first node, aka root node. -// rootIntermediateNode ??= result; - -// if (result != null) { -// // Add next depth to queue. -// if (currentNode.designNode is GroupNode && -// (currentNode.designNode as GroupNode).children != null && -// (currentNode.designNode as GroupNode).children.isNotEmpty) { -// for (var child -// in (currentNode.designNode as GroupNode).children) { -// queue.add(NodeTuple(child, result)); -// } -// } -// } -// } -// } -// } -// // TODO: This should be replaced for something more optimal or done in some other class -// if (originalRoot.prototypeNodeUUID != null) { -// var prototypeNode = PrototypeNode(originalRoot.prototypeNodeUUID); -// var destHolder = PBDestHolder( -// rootIntermediateNode.topLeftCorner, -// rootIntermediateNode.bottomRightCorner, -// rootIntermediateNode.UUID, -// prototypeNode, -// rootIntermediateNode.currentContext); -// destHolder.addChild(rootIntermediateNode); -// return destHolder; -// } -// if (rootIntermediateNode != null) { -// _extractScreenSize(rootIntermediateNode); -// } -// return rootIntermediateNode; -// } - -// ///Sets the size of the UI element. -// /// -// ///We are assuming that since the [rootIntermediateNode] contains all of the nodes -// ///then it should represent the biggest screen size that encapsulates the entire UI elements. -// void _extractScreenSize(PBIntermediateNode rootIntermediateNode) { -// if ((currentContext.screenBottomRightCorner == null && -// currentContext.screenTopLeftCorner == null) || -// (currentContext.screenBottomRightCorner != -// rootIntermediateNode.bottomRightCorner || -// currentContext.screenTopLeftCorner != -// rootIntermediateNode.bottomRightCorner)) { -// currentContext.screenBottomRightCorner = -// rootIntermediateNode.bottomRightCorner; -// currentContext.screenTopLeftCorner = rootIntermediateNode.topLeftCorner; -// } -// } - -// void _addToParent(PBIntermediateNode parentNode, -// PBIntermediateNode convertedChildNode) => -// parentNode.addChild(convertedChildNode); -// } diff --git a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart index b0e1b4ae..201260e1 100644 --- a/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart +++ b/lib/interpret_and_optimize/value_objects/pb_symbol_master_params.dart @@ -24,22 +24,20 @@ class PBSymbolMasterParameter extends PBIntermediateNode ChildrenStrategy childrenStrategy = NoChildStrategy(); PBSymbolMasterParameter( - String name, - this.type, - this.parameterID, - this.canOverride, - this.propertyName, - this.parameterDefinition, - this.topLeftX, - this.topLeftY, - this.bottomRightX, - this.bottomRightY, - {this.context}) - : super( + String name, + this.type, + this.parameterID, + this.canOverride, + this.propertyName, + this.parameterDefinition, + this.topLeftX, + this.topLeftY, + this.bottomRightX, + this.bottomRightY, + ) : super( null, null, name, - currentContext: context, ); static String _typeToJson(type) { diff --git a/lib/main.dart b/lib/main.dart index 77642175..7bdb6608 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,7 +5,9 @@ import 'package:parabeac_core/generation/flutter_project_builder/file_system_ana import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart'; @@ -23,7 +25,7 @@ final designToPBDLServices = [ FigmaToPBDLService(), ]; FileSystemAnalyzer fileSystemAnalyzer; -Interpret interpretService; +Interpret interpretService = Interpret(); ///sets up parser final parser = ArgParser() @@ -107,15 +109,22 @@ ${parser.usage} (service) => service.designType == processInfo.designType, ); var pbdl = await pbdlService.callPBDL(processInfo); - var intermediateProject = await interpretService.interpretAndOptimize( - pbdl, MainInfo().configuration); + var pbProject = PBProject.fromJson(pbdl.toJson()); + pbProject.projectAbsPath = + p.join(processInfo.outputPath, processInfo.projectName); var fpb = FlutterProjectBuilder( MainInfo().configuration.generationConfiguration, fileSystemAnalyzer, - project: intermediateProject, pageWriter: PBFlutterWriter()); - + project: pbProject); + await fpb.preGenTasks(); await indexFileFuture; - await fpb.genProjectFiles(processInfo.genProjectPath); + + await Future.wait(pbProject.forest.map((tree) { + var context = PBContext(processInfo.configuration); + return interpretService + .interpretAndOptimize(tree, context, pbProject) + .then((tree) => fpb.genAITree(tree, context)); + }).toList()); exitCode = 0; } diff --git a/pbdl b/pbdl index be8bad26..252b8e42 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit be8bad265ff46e82e1324174e8a0ddfbe2da9727 +Subproject commit 252b8e423c81d0265fcbc9f61c92f8b777d33acd From 8faf0829803c47298f1e61de8ef5e2ae5dab389e Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 11 Aug 2021 21:03:23 -0600 Subject: [PATCH 284/404] WIP fixing the issue regarding layout generation --- SketchAssetConverter | 1 + .../state_management/bloc_middleware.dart | 4 +- .../state_management/provider_middleware.dart | 2 +- .../helper/figma_constraint_to_pbdl.dart | 2 +- .../entities/inherited_shape_path.dart | 4 +- .../subclasses/pb_intermediate_node.dart | 8 +- .../helpers/child_strategy.dart | 5 +- .../helpers/pb_intermediate_node_tree.dart | 2 +- .../pb_layout_generation_service.dart | 124 +++++++++--------- .../services/pb_plugin_control_service.dart | 7 +- .../services/pb_symbol_linker_service.dart | 2 +- 11 files changed, 84 insertions(+), 77 deletions(-) create mode 160000 SketchAssetConverter diff --git a/SketchAssetConverter b/SketchAssetConverter new file mode 160000 index 00000000..1b5effbd --- /dev/null +++ b/SketchAssetConverter @@ -0,0 +1 @@ +Subproject commit 1b5effbd220ff03015bc4b288184005e4443f056 diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index a0633fea..030fd7d0 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -205,10 +205,10 @@ class BLoCMiddleware extends StateManagementMiddleware { } } importBuffer.write( - "import 'package:${MainInfo().projectName}/widgets/${elementName}/${node.name.snakeCase}.dart'; \n"); + "import 'package:${MainInfo().projectName}/widgets/$elementName/${node.name.snakeCase}.dart'; \n"); } importBuffer.write( - "import 'package:${MainInfo().projectName}/widgets/${elementName}/${element.name.snakeCase}.dart'; \n"); + "import 'package:${MainInfo().projectName}/widgets/$elementName/${element.name.snakeCase}.dart'; \n"); stateBuffer.write('return ${element.name.pascalCase}(constraints); \n }'); return importBuffer.toString() + stateBuffer.toString(); diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index bc809ade..d16b4eb7 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -77,7 +77,7 @@ class ProviderMiddleware extends StateManagementMiddleware { return GestureDetector( onTap: () => context.read< - ${modelName}>().onGesture(), + $modelName>().onGesture(), child: Consumer<$modelName>( builder: (context, ${modelName.toLowerCase()}, child) => ${modelName.toLowerCase()}.currentWidget ), diff --git a/lib/input/helper/figma_constraint_to_pbdl.dart b/lib/input/helper/figma_constraint_to_pbdl.dart index d494ab16..446f5030 100644 --- a/lib/input/helper/figma_constraint_to_pbdl.dart +++ b/lib/input/helper/figma_constraint_to_pbdl.dart @@ -58,7 +58,7 @@ PBDLConstraints _convertFigmaConstraint(FigmaConstraintType figmaConstraintType, constraints.fixedWidth = false; } else { print( - 'We currently do not support Figma Constraint Type: ${figmaConstraintType}'); + 'We currently do not support Figma Constraint Type: $figmaConstraintType'); } return constraints; } diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 63612f24..aa8db429 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -89,8 +89,8 @@ class InheritedShapePath extends PBVisualIntermediateNode /// Returns true if [p1] and [p2] form /// either a vertical or horizontal line. bool _isEdgeAdjacent(Point p1, Point p2) { - num deltaX = (p1.x - p2.x).abs(); - num deltaY = (p1.y - p2.y).abs(); + var deltaX = (p1.x - p2.x).abs(); + var deltaY = (p1.y - p2.y).abs(); var isVertical = deltaX < 0.01 && deltaY > 0; var isHorizontal = deltaY < 0.01 && deltaX > 0; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 4d67ebc1..3c047875 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -21,7 +21,7 @@ part 'pb_intermediate_node.g.dart'; @JsonSerializable( explicitToJson: true, createFactory: false, ignoreUnannotated: true) -abstract class PBIntermediateNode extends Iterable +abstract class PBIntermediateNode //extends Iterable implements TraversableNode { @JsonKey(ignore: true) Logger logger; @@ -74,9 +74,9 @@ abstract class PBIntermediateNode extends Iterable @JsonKey(ignore: true) PBIntermediateNode get child => children.isEmpty ? null : children.first; - @override - @JsonKey(ignore: true) - Iterator get iterator => children.iterator; + // @override + // @JsonKey(ignore: true) + // Iterator get iterator => children.iterator; @JsonKey(ignore: true) ChildrenStrategy childrenStrategy = OneChildStrategy('child'); diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 81bdeb42..b57234b7 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -40,8 +40,9 @@ class MultipleChildStrategy extends ChildrenStrategy { return child; })); } else if (children is PBIntermediateNode) { - children.parent = target; - children.forEach(target.addChild); + var node = children; + node.parent = target; + node.children.forEach(target.addChild); } } } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 5b1ec117..18f4f18a 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -8,7 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart'; import 'package:recase/recase.dart'; import 'package:tuple/tuple.dart'; -import "dart:collection"; +import 'dart:collection'; import 'package:uuid/uuid.dart'; import 'package:json_annotation/json_annotation.dart'; diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index dd7b7de9..428d0645 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -64,29 +64,34 @@ class PBLayoutGenerationService extends AITHandler { return Future.value(tree); } try { - var removedList = tree.toList() - ..removeWhere((node) => node is TempGroupLayoutNode); - tree.rootNode = removedList.first; - // tree.forEach((att) => _removingMeaninglessGroup(att.attributeNode)); - rootNode = (tree - .map((node) => _removingMeaninglessGroup(node)) - .map((node) => _transformGroup(node)) - .map((node) => _layoutConditionalReplacement(node, context)) - .toList() - ..removeWhere((element) => element == null)) - .first; - // rootNode = _traverseLayersUtil(rootNode, (layer) { - // return layer - /// [rootNode -> scaffold], [scaffold, container], [temp, bitmap], [container, bitmap] + // var removedList = tree.toList() + // ..removeWhere((node) => node is TempGroupLayoutNode); + // tree + // .whereType() + // .forEach((group) => group.parent.children.remove(group)); + // tree.rootNode = removedList.first; + // // tree.forEach((att) => _removingMeaninglessGroup(att.attributeNode)); + // rootNode = (tree + // // .map((node) => _removingMeaninglessGroup(node)) + // .map((node) => _transformGroup(node)) + // .map((node) => _layoutConditionalReplacement(node, context)) + // .toList() + // ..removeWhere((element) => element == null)) + // .first; - // ///Remove the `TempGroupLayout` nodes that only contain one node - // .map(_removingMeaninglessGroup) - // .map((node) => _layoutConditionalReplacement(node, context)) - // .toList() + var l = tree.toList()..map((_removingMeaninglessGroup)); + tree.rootNode = l.first; + rootNode = _traverseLayersUtil(rootNode, (layer) { + // return layer - // /// Filter out the elements that are null in the tree - // ..removeWhere((element) => element == null); - // }); + // ///Remove the `TempGroupLayout` nodes that only contain one node + // .map(_removingMeaninglessGroup) + // .map((node) => _layoutConditionalReplacement(node, context)) + // .toList() + + // /// Filter out the elements that are null in the tree + // ..removeWhere((element) => element == null); + }); ///After all the layouts are generated, the [PostConditionRules] are going ///to be applyed to the layerss @@ -104,45 +109,46 @@ class PBLayoutGenerationService extends AITHandler { } } - // PBIntermediateNode _traverseLayersUtil( - // PBIntermediateNode rootNode, - // List Function(List layer) - // transformation) { - // ///The stack is going to saving the current layer of tree along with the parent of - // ///the layer. It makes use of a `Tuple2()` to save the parent in the first index and a list - // ///of nodes for the current layer in the second layer. - // var stack = >>[]; - // stack.add(Tuple2(null, [ - // PBAttribute('root', attributeNodes: [rootNode]) - // ])); + PBIntermediateNode _traverseLayersUtil( + PBIntermediateNode rootNode, + List Function(List layer) + transformation) { + ///The stack is going to saving the current layer of tree along with the parent of + ///the layer. It makes use of a `Tuple2()` to save the parent in the first index and a list + ///of nodes for the current layer in the second layer. + var stack = >>[]; + stack.add(Tuple2(null, [rootNode])); + + while (stack.isNotEmpty) { + var currentTuple = stack.removeLast(); + var children = currentTuple.item2; + var node = currentTuple.item1; - // while (stack.isNotEmpty) { - // var currentTuple = stack.removeLast(); - // currentTuple.item2.forEach((currentAttribute) { - // currentAttribute.attributeNodes = - // transformation(currentAttribute.attributeNodes); - // currentAttribute?.attributeNodes?.forEach((currentNode) { - // currentNode?.attributes?.forEach((attribute) { - // stack.add(Tuple2(currentNode, [ - // PBAttribute(attribute.attributeName, - // attributeNodes: attribute.attributeNodes) - // ])); - // }); - // }); - // }); - // var node = currentTuple.item1; - // if (node != null) { - // currentTuple.item2.forEach((attribute) { - // node.addAttribute(attribute, overwrite: true); - // }); - // } else { - // ///if the `currentTuple.item1` is null, that implies the `currentTuple.item2.first` is the - // ///new `rootNode`. - // rootNode = currentTuple.item2.first.attributeNode; - // } - // } - // return rootNode; - // } + stack.add(Tuple2(node, node.children)); + node.children = transformation(node.children); + children.forEach((child) { + // child = transformation(child); + + // child?.attributeNodes?.forEach((currentNode) { + // currentNode?.attributes?.forEach((attribute) { + // stack.add(Tuple2(currentNode, [ + // // currentNode. + // ])); + // }); + // }); + }); + if (node != null) { + currentTuple.item2.forEach((attribute) { + // node.addAttribute(attribute, overwrite: true); + }); + } else { + ///if the `currentTuple.item1` is null, that implies the `currentTuple.item2.first` is the + ///new `rootNode`. + // rootNode = currentTuple.item2.first.attributeNode; + } + } + return rootNode; + } /// If this node is an unecessary [TempGroupLayoutNode], just return the child or an /// [InjectContainer] if the group is empty diff --git a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart index c0e9b526..558371c3 100644 --- a/lib/interpret_and_optimize/services/pb_plugin_control_service.dart +++ b/lib/interpret_and_optimize/services/pb_plugin_control_service.dart @@ -53,8 +53,7 @@ class PBPluginControlService extends AITHandler { assert(currentLayer.nodeLayer.length <= 1, '[Plugin Control Service] We are going to end up deleting nodes here, something probably went wrong.'); (currentLayer.parent as PBVisualIntermediateNode).replaceAttribute( - currentLayer.parent.first.attributeName, - currentLayer.nodeLayer[0]); + currentLayer.parent.attributeName, currentLayer.nodeLayer[0]); } else if (currentLayer.parent is PBLayoutIntermediateNode) { (currentLayer.parent as PBLayoutIntermediateNode) .replaceChildren(currentLayer.nodeLayer, context); @@ -63,8 +62,8 @@ class PBPluginControlService extends AITHandler { /// Add next depth layer to queue. if (currentIntermediateNode is PBVisualIntermediateNode && currentIntermediateNode.child != null) { - queue.add(LayerTuple([currentIntermediateNode.child], - currentIntermediateNode)); + queue.add(LayerTuple( + [currentIntermediateNode.child], currentIntermediateNode)); } else if (currentIntermediateNode is PBLayoutIntermediateNode && currentIntermediateNode.children != null) { queue.add(LayerTuple( diff --git a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart index 6564af75..58824b61 100644 --- a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart @@ -26,7 +26,7 @@ class PBSymbolLinkerService extends AITHandler { return Future.value(tree); } - for (PBIntermediateNode node in tree) { + for (var node in tree) { if (node is PBSharedMasterNode) { await _symbolStorage.addSharedMasterNode(node); _aggregationService.gatherSharedParameters(node, node.child); From 0bd306887f302b1e9830badea00928a19486090e Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 12 Aug 2021 15:20:30 -0600 Subject: [PATCH 285/404] CREATED a couple of unit test for modification of the tree elements --- .../subclasses/pb_intermediate_node.dart | 48 ++++++++++++++-- .../helpers/pb_intermediate_node_tree.dart | 55 ++++++++++++++++++- .../helpers/shapes_utils.dart | 47 ---------------- 3 files changed, 95 insertions(+), 55 deletions(-) delete mode 100644 lib/interpret_and_optimize/helpers/shapes_utils.dart diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 3c047875..2d890b28 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; // import 'dart:math'; @@ -74,9 +75,6 @@ abstract class PBIntermediateNode //extends Iterable @JsonKey(ignore: true) PBIntermediateNode get child => children.isEmpty ? null : children.first; - // @override - // @JsonKey(ignore: true) - // Iterator get iterator => children.iterator; @JsonKey(ignore: true) ChildrenStrategy childrenStrategy = OneChildStrategy('child'); @@ -313,11 +311,49 @@ extension PBPointLegacyMethod on Point { } extension DeserializedRectangle on Rectangle { - Point get topLeftCorner => topLeft; - Point get bottomRightCorner => bottomRight; + bool _areXCoordinatesOverlapping( + Point topLeftCorner0, + Point bottomRightCorner0, + Point topLeftCorner1, + Point bottomRightCorner1) => + topLeftCorner1.x >= topLeftCorner0.x && + topLeftCorner1.x <= bottomRightCorner0.x || + bottomRightCorner1.x <= bottomRightCorner0.x && + bottomRightCorner1.x >= topLeftCorner0.x; + + bool _areYCoordinatesOverlapping( + Point topLeftCorner0, + Point bottomRightCorner0, + Point topLeftCorner1, + Point bottomRightCorner1) => + topLeftCorner1.y >= topLeftCorner0.y && + topLeftCorner1.y <= bottomRightCorner0.y || + bottomRightCorner1.y <= bottomRightCorner0.y && + bottomRightCorner1.y >= topLeftCorner0.y; + + bool isHorizontalTo(Rectangle frame) { + return (!(_areXCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight))) && + _areYCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight); + } + + bool isVerticalTo(Rectangle frame) { + return (!(_areYCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight))) && + _areXCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight); + } + + bool isOverlappingTo(Rectangle frame) { + return (_areXCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight)) && + _areYCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight); + } static Rectangle fromJson(Map json) { - return Rectangle(json['x'], json['y'], json['width'], json['height']); + return Rectangle(json['x'], json['y'], json['width'], json['height']); } static Map toJson(Rectangle rectangle) => { diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 18f4f18a..fb51c47c 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -113,6 +113,58 @@ class PBIntermediateTree extends Iterable } } + /// Removing the [node] from the [PBIntermediateTree] + /// + /// The entire subtree (starting with [node]) would be eliminated if specified to [eliminateSubTree], + /// otherwise, its just going to replace [node] with its [node.children] + bool removeNode(PBIntermediateNode node, {bool eliminateSubTree = false}) { + if (node.parent == null) { + ///TODO: log message + return false; + } + var parent = node.parent; + var removeChild = () => + parent.children.removeWhere((element) => element.UUID == node.UUID); + + if (eliminateSubTree) { + removeChild(); + } else { + /// appending the [PBIntermediateNode]s of the removed [node] + var grandChilds = parent.children + .where((element) => element.UUID == node.UUID) + .map((e) => e.children) + ///FIXME: Right now the iterator is returning null insize of a list when iterating the tree. + .where((element) => element != null) + .expand((element) => element) + .toList(); + removeChild(); + grandChilds.forEach((element) => parent.addChild(element)); + } + return true; + } + + /// Replacing [target] with [replacement] + /// + /// The entire subtree (starting with [target]) if [replacement] does not [acceptChildren], + /// otherwise, those children would be appended to [replacement]. + bool replaceNode(PBIntermediateNode target, PBIntermediateNode replacement, + {bool acceptChildren = false}) { + if (target.parent == null) { + ///TODO: throw correct error/log + return false; + } + + var parent = target.parent; + var orphans = []; + if (acceptChildren) { + orphans.addAll(target.children); + } + removeNode(target, eliminateSubTree: true); + replacement.children.addAll(orphans); + parent.children.add(replacement); + return true; + } + /// Checks if the [PBIntermediateTree] is a [TREE_TYPE.SCREEN], /// meaning that the [rootNode] is of type [InheritedScaffold] bool isScreen() => tree_type == TREE_TYPE.SCREEN; @@ -174,8 +226,7 @@ class PBIntermediateTree extends Iterable @override Iterator get iterator => IntermediateDFSIterator(this); - Iterator get layerIterator => - IntermediateLayerIterator(this); + Iterator get layerIterator => IntermediateLayerIterator(this); Map toJson() => _$PBIntermediateTreeToJson(this); diff --git a/lib/interpret_and_optimize/helpers/shapes_utils.dart b/lib/interpret_and_optimize/helpers/shapes_utils.dart deleted file mode 100644 index 3680cb93..00000000 --- a/lib/interpret_and_optimize/helpers/shapes_utils.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'dart:math'; - -class ShapesComparisonUtils { - static bool areXCoordinatesOverlapping( - Point topLeftCorner0, - Point bottomRightCorner0, - Point topLeftCorner1, - Point bottomRightCorner1) => - topLeftCorner1.x >= topLeftCorner0.x && - topLeftCorner1.x <= bottomRightCorner0.x || - bottomRightCorner1.x <= bottomRightCorner0.x && - bottomRightCorner1.x >= topLeftCorner0.x; - - static bool areYCoordinatesOverlapping( - Point topLeftCorner0, - Point bottomRightCorner0, - Point topLeftCorner1, - Point bottomRightCorner1) => - topLeftCorner1.y >= topLeftCorner0.y && - topLeftCorner1.y <= bottomRightCorner0.y || - bottomRightCorner1.y <= bottomRightCorner0.y && - bottomRightCorner1.y >= topLeftCorner0.y; - - static bool isHorizontalTo(Point topLeftCorner, Point bottomRightCorner, - Point topLeftCorner0, Point bottomRightCorner0) { - return (!(areXCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0))) && - areYCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0); - } - - static bool isVerticalTo(Point topLeftCorner, Point bottomRightCorner, - Point topLeftCorner0, Point bottomRightCorner0) { - return (!(areYCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0))) && - areXCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0); - } - - static bool isOverlappingTo(Point topLeftCorner, Point bottomRightCorner, - Point topLeftCorner0, Point bottomRightCorner0) { - return (areXCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0)) && - areYCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0); - } - } \ No newline at end of file From f39ca489cca0b8e8661d49c28923c9378fdffe2c Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 12 Aug 2021 15:20:30 -0600 Subject: [PATCH 286/404] CREATED a couple of unit test for modification of the tree elements --- .../subclasses/pb_intermediate_node.dart | 48 ++++- .../helpers/pb_intermediate_node_tree.dart | 55 +++++- .../helpers/shapes_utils.dart | 47 ----- .../intermediate_tree_test.dart | 175 ++++++++++++++++++ 4 files changed, 270 insertions(+), 55 deletions(-) delete mode 100644 lib/interpret_and_optimize/helpers/shapes_utils.dart create mode 100644 test/lib/interpret_and_optimize/intermediate_tree_test.dart diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 3c047875..2d890b28 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; // import 'dart:math'; @@ -74,9 +75,6 @@ abstract class PBIntermediateNode //extends Iterable @JsonKey(ignore: true) PBIntermediateNode get child => children.isEmpty ? null : children.first; - // @override - // @JsonKey(ignore: true) - // Iterator get iterator => children.iterator; @JsonKey(ignore: true) ChildrenStrategy childrenStrategy = OneChildStrategy('child'); @@ -313,11 +311,49 @@ extension PBPointLegacyMethod on Point { } extension DeserializedRectangle on Rectangle { - Point get topLeftCorner => topLeft; - Point get bottomRightCorner => bottomRight; + bool _areXCoordinatesOverlapping( + Point topLeftCorner0, + Point bottomRightCorner0, + Point topLeftCorner1, + Point bottomRightCorner1) => + topLeftCorner1.x >= topLeftCorner0.x && + topLeftCorner1.x <= bottomRightCorner0.x || + bottomRightCorner1.x <= bottomRightCorner0.x && + bottomRightCorner1.x >= topLeftCorner0.x; + + bool _areYCoordinatesOverlapping( + Point topLeftCorner0, + Point bottomRightCorner0, + Point topLeftCorner1, + Point bottomRightCorner1) => + topLeftCorner1.y >= topLeftCorner0.y && + topLeftCorner1.y <= bottomRightCorner0.y || + bottomRightCorner1.y <= bottomRightCorner0.y && + bottomRightCorner1.y >= topLeftCorner0.y; + + bool isHorizontalTo(Rectangle frame) { + return (!(_areXCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight))) && + _areYCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight); + } + + bool isVerticalTo(Rectangle frame) { + return (!(_areYCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight))) && + _areXCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight); + } + + bool isOverlappingTo(Rectangle frame) { + return (_areXCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight)) && + _areYCoordinatesOverlapping( + topLeft, bottomRight, frame.topLeft, frame.bottomRight); + } static Rectangle fromJson(Map json) { - return Rectangle(json['x'], json['y'], json['width'], json['height']); + return Rectangle(json['x'], json['y'], json['width'], json['height']); } static Map toJson(Rectangle rectangle) => { diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 18f4f18a..fb51c47c 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -113,6 +113,58 @@ class PBIntermediateTree extends Iterable } } + /// Removing the [node] from the [PBIntermediateTree] + /// + /// The entire subtree (starting with [node]) would be eliminated if specified to [eliminateSubTree], + /// otherwise, its just going to replace [node] with its [node.children] + bool removeNode(PBIntermediateNode node, {bool eliminateSubTree = false}) { + if (node.parent == null) { + ///TODO: log message + return false; + } + var parent = node.parent; + var removeChild = () => + parent.children.removeWhere((element) => element.UUID == node.UUID); + + if (eliminateSubTree) { + removeChild(); + } else { + /// appending the [PBIntermediateNode]s of the removed [node] + var grandChilds = parent.children + .where((element) => element.UUID == node.UUID) + .map((e) => e.children) + ///FIXME: Right now the iterator is returning null insize of a list when iterating the tree. + .where((element) => element != null) + .expand((element) => element) + .toList(); + removeChild(); + grandChilds.forEach((element) => parent.addChild(element)); + } + return true; + } + + /// Replacing [target] with [replacement] + /// + /// The entire subtree (starting with [target]) if [replacement] does not [acceptChildren], + /// otherwise, those children would be appended to [replacement]. + bool replaceNode(PBIntermediateNode target, PBIntermediateNode replacement, + {bool acceptChildren = false}) { + if (target.parent == null) { + ///TODO: throw correct error/log + return false; + } + + var parent = target.parent; + var orphans = []; + if (acceptChildren) { + orphans.addAll(target.children); + } + removeNode(target, eliminateSubTree: true); + replacement.children.addAll(orphans); + parent.children.add(replacement); + return true; + } + /// Checks if the [PBIntermediateTree] is a [TREE_TYPE.SCREEN], /// meaning that the [rootNode] is of type [InheritedScaffold] bool isScreen() => tree_type == TREE_TYPE.SCREEN; @@ -174,8 +226,7 @@ class PBIntermediateTree extends Iterable @override Iterator get iterator => IntermediateDFSIterator(this); - Iterator get layerIterator => - IntermediateLayerIterator(this); + Iterator get layerIterator => IntermediateLayerIterator(this); Map toJson() => _$PBIntermediateTreeToJson(this); diff --git a/lib/interpret_and_optimize/helpers/shapes_utils.dart b/lib/interpret_and_optimize/helpers/shapes_utils.dart deleted file mode 100644 index 3680cb93..00000000 --- a/lib/interpret_and_optimize/helpers/shapes_utils.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'dart:math'; - -class ShapesComparisonUtils { - static bool areXCoordinatesOverlapping( - Point topLeftCorner0, - Point bottomRightCorner0, - Point topLeftCorner1, - Point bottomRightCorner1) => - topLeftCorner1.x >= topLeftCorner0.x && - topLeftCorner1.x <= bottomRightCorner0.x || - bottomRightCorner1.x <= bottomRightCorner0.x && - bottomRightCorner1.x >= topLeftCorner0.x; - - static bool areYCoordinatesOverlapping( - Point topLeftCorner0, - Point bottomRightCorner0, - Point topLeftCorner1, - Point bottomRightCorner1) => - topLeftCorner1.y >= topLeftCorner0.y && - topLeftCorner1.y <= bottomRightCorner0.y || - bottomRightCorner1.y <= bottomRightCorner0.y && - bottomRightCorner1.y >= topLeftCorner0.y; - - static bool isHorizontalTo(Point topLeftCorner, Point bottomRightCorner, - Point topLeftCorner0, Point bottomRightCorner0) { - return (!(areXCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0))) && - areYCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0); - } - - static bool isVerticalTo(Point topLeftCorner, Point bottomRightCorner, - Point topLeftCorner0, Point bottomRightCorner0) { - return (!(areYCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0))) && - areXCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0); - } - - static bool isOverlappingTo(Point topLeftCorner, Point bottomRightCorner, - Point topLeftCorner0, Point bottomRightCorner0) { - return (areXCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0)) && - areYCoordinatesOverlapping(topLeftCorner, bottomRightCorner, - topLeftCorner0, bottomRightCorner0); - } - } \ No newline at end of file diff --git a/test/lib/interpret_and_optimize/intermediate_tree_test.dart b/test/lib/interpret_and_optimize/intermediate_tree_test.dart new file mode 100644 index 00000000..c8a77f49 --- /dev/null +++ b/test/lib/interpret_and_optimize/intermediate_tree_test.dart @@ -0,0 +1,175 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:test/test.dart'; +import 'package:mockito/mockito.dart'; + +class MockContainer extends Mock implements PBIntermediateNode {} + +class MockContainerBuilder { + static MockContainer buildContainer(String UUID, + {List children, MockContainer parent}) { + var container = MockContainer(); + when(container.UUID).thenReturn(UUID); + when(container.children).thenReturn(children); + when(container.parent).thenReturn(parent); + return container; + } +} + +class TreeBuilder { + num numberOfContainers; + List _containerList; + T rootNode; + + var nodeBuilder; + var rootNodeBuilder; + + TreeBuilder(this.numberOfContainers, + {T Function(int index) this.nodeBuilder, + T Function(List children, T rootNode) this.rootNodeBuilder}) { + nodeBuilder ??= _mockContainerBuilder; + rootNodeBuilder ??= _rootNodeBuilder; + } + + T _mockContainerBuilder(int idx, T rootNode) { + var container = MockContainer(); + + var containerChild = MockContainer(); + when(containerChild.UUID).thenReturn(('C_$idx')); + when(containerChild.parent).thenReturn(container); + + when(container.children).thenReturn([containerChild]); + when(container.UUID).thenReturn('P_$idx'); + when(container.parent).thenReturn(rootNode); + + return container as T; + } + + T _rootNodeBuilder() { + var rootNode = MockContainer(); + when(rootNode.UUID).thenReturn('R_123'); + return rootNode as T; + } + + PBIntermediateTree build() { + rootNode = rootNodeBuilder(); + _containerList = List.generate( + (numberOfContainers ~/ 2), (index) => nodeBuilder(index, rootNode)); + when(rootNode.children).thenReturn(_containerList); + + var tree = PBIntermediateTree(name: 'Example'); + tree.rootNode = rootNode; + + ///Taking into account the [rootNode] + numberOfContainers++; + return tree; + } +} + +void main() { + var numberOfContainers; + var rootNode; + TreeBuilder treeBuilder; + PBIntermediateTree tree; + group('Testing the PBIntermediateTree', () { + setUp(() { + ///This is the tree that is going to be build: + /// [R_123] + /// | + /// [P_0, P_1, P_2, P_3, P_4] + /// | | | | | + /// [C_0][C_1][C_2][C_3][C_4] + /// + + numberOfContainers = 10; + treeBuilder = TreeBuilder(numberOfContainers); + tree = treeBuilder.build(); + rootNode = treeBuilder.rootNode; + }); + + test('Replacement of through [$PBIntermediateNode]', () { + var replacementChild3 = MockContainerBuilder.buildContainer( + 'REPLACEMENT_C3', + parent: null, + children: []); + var parentReplacement4 = MockContainerBuilder.buildContainer( + 'REPLACEMENT_P4', + parent: null, + children: []); + var find = (UUID) => + tree.firstWhere((node) => node.UUID == UUID, orElse: () => null); + + var targetChild3 = find('C_3'); + var targetParent4 = find('P_4'); + var targetChild4 = find('C_4'); + + expect(targetChild3, isNotNull); + expect(targetParent4, isNotNull); + + expect(tree.replaceNode(targetChild3, replacementChild3), isTrue); + expect(find(targetChild3.UUID), isNull); + + expect( + tree.replaceNode(targetParent4, parentReplacement4, + acceptChildren: true), + isTrue); + expect(find(targetParent4.UUID), isNull); + expect(find(targetChild4.UUID), isNotNull, + reason: + 'The ${targetChild4.UUID} is not part of the $parentReplacement4 children'); + + // reset(rootNode); + // reset(containerList); + }); + + test('Testing the removal of nodes from the tree', () { + var child3 = tree.firstWhere((child) => child.UUID == 'C_3'); + var parent4 = tree.firstWhere((parent) => parent.UUID == 'P_4'); + var child4 = tree.firstWhere((child) => child.UUID == 'C_4'); + + expect(child3, isNotNull); + expect(parent4, isNotNull); + expect(child4, isNotNull); + + expect(tree.removeNode(child3), isTrue); + expect( + tree.firstWhere((child) => child.UUID == child3.UUID, + orElse: () => null), + isNull); + + expect(tree.removeNode(parent4, eliminateSubTree: true), isTrue); + expect( + tree.firstWhere((parent) => parent.UUID == parent4.UUID, + orElse: () => null), + isNull); + expect( + tree.firstWhere((child) => child.UUID == child4.UUID, + orElse: () => null), + isNull, + reason: + '${child4.UUID} should have been removed of the ${tree.runtimeType} as consequence of deleting its parent'); + // reset(rootNode); + // reset(containerList); + }); + + test('Testing the traversal of the IntermediateTree', () { + expect(tree.length, treeBuilder.numberOfContainers); + expect(tree.first, rootNode); + }); + + test( + 'Testing [PBIntermediateTree.dist] function, see if it gives the correct distance between two nodes', + () { + var child = tree.firstWhere((node) => node.UUID == 'C_0'); + expect(child, isNotNull); + expect(tree.depthOf(child), 2); + + var parent = tree.firstWhere((node) => node.UUID == 'P_0'); + expect(parent, isNotNull); + expect(tree.depthOf(parent), 1); + + expect(rootNode, isNotNull); + expect(tree.depthOf(rootNode), 0); + }); + }); +} From afb476603e24af112503ec00d1b9869edf98b86d Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 12 Aug 2021 15:32:43 -0600 Subject: [PATCH 287/404] FIX the removal of "Unecessary" temp group layouts nodes. --- .../pb_layout_generation_service.dart | 39 ++++---- .../dfs_iterator_test.dart | 95 ------------------- 2 files changed, 22 insertions(+), 112 deletions(-) delete mode 100644 test/lib/interpret_and_optimize/dfs_iterator_test.dart diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 428d0645..43b6fac9 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -79,8 +79,8 @@ class PBLayoutGenerationService extends AITHandler { // ..removeWhere((element) => element == null)) // .first; - var l = tree.toList()..map((_removingMeaninglessGroup)); - tree.rootNode = l.first; + tree = _removingMeaninglessGroup(tree); + // tree.rootNode = l.first; rootNode = _traverseLayersUtil(rootNode, (layer) { // return layer @@ -150,24 +150,29 @@ class PBLayoutGenerationService extends AITHandler { return rootNode; } - /// If this node is an unecessary [TempGroupLayoutNode], just return the child or an - /// [InjectContainer] if the group is empty + /// If this node is an unecessary [TempGroupLayoutNode], from the [tree] /// /// Ex: Designer put a group with one child that was a group /// and that group contained the visual nodes. - PBIntermediateNode _removingMeaninglessGroup(PBIntermediateNode tempGroup) { - while (tempGroup is TempGroupLayoutNode && tempGroup.children.length <= 1) { - tempGroup = (tempGroup as TempGroupLayoutNode).children.isNotEmpty - ? _replaceNode( - tempGroup, (tempGroup as TempGroupLayoutNode).children[0]) - : _replaceNode( - tempGroup, - InjectedContainer( - tempGroup.UUID, tempGroup.frame, name: tempGroup.name, - // constraints: tempGroup.constraints - )); - } - return tempGroup; + PBIntermediateTree _removingMeaninglessGroup(PBIntermediateTree tree) { + tree + .where( + (node) => node is TempGroupLayoutNode && node.children.length <= 1) + .cast() + .forEach((tempGroup) { + tree.replaceNode( + tempGroup, + tempGroup.children.isNotEmpty + ? _replaceNode(tempGroup, tempGroup.children.first) + : _replaceNode( + tempGroup, + InjectedContainer( + tempGroup.UUID, tempGroup.frame, + name: tempGroup.name, + // constraints: tempGroup.constraints + ))); + }); + return tree; } /// Transforming the [TempGroupLayoutNode] into regular [PBLayoutIntermediateNode] diff --git a/test/lib/interpret_and_optimize/dfs_iterator_test.dart b/test/lib/interpret_and_optimize/dfs_iterator_test.dart deleted file mode 100644 index 4fa37225..00000000 --- a/test/lib/interpret_and_optimize/dfs_iterator_test.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:test/test.dart'; -import 'package:mockito/mockito.dart'; - -class MockContainer extends Mock implements PBIntermediateNode {} - -class TreeBuilder { - num numberOfContainers; - List _containerList; - T rootNode; - - var nodeBuilder; - var rootNodeBuilder; - - TreeBuilder(this.numberOfContainers, - {T Function(int index) this.nodeBuilder, - T Function(List children) this.rootNodeBuilder}) { - nodeBuilder ??= _mockContainerBuilder; - rootNodeBuilder ??= _rootNodeBuilder; - } - - T _mockContainerBuilder(int idx) { - var container = MockContainer(); - - var containerChild = MockContainer(); - when(containerChild.UUID).thenReturn(('C_$idx')); - - when(container.children).thenReturn([containerChild]); - when(container.UUID).thenReturn('P_$idx'); - return container as T; - } - - T _rootNodeBuilder(List children) { - var rootNode = MockContainer(); - when(rootNode.UUID).thenReturn('R_123'); - when(rootNode.children).thenReturn(_containerList); - return rootNode as T; - } - - PBIntermediateTree build() { - _containerList = List.generate((numberOfContainers ~/ 2), nodeBuilder); - rootNode = rootNodeBuilder(_containerList); - - var tree = PBIntermediateTree('Example'); - tree.rootNode = rootNode; - - ///Taking into account the [rootNode] - numberOfContainers++; - return tree; - } -} - -void main() { - var numberOfContainers; - var rootNode; - TreeBuilder treeBuilder; - PBIntermediateTree tree; - group('Testing the PBIntermediateTree', () { - setUp(() { - ///This is the tree that is going to be build: - /// [R_123] - /// | - /// [P_0, P_1, P_2, P_3, P_4] - /// | | | | | - /// [C_0][C_1][C_2][C_3][C_4] - /// - - numberOfContainers = 10; - treeBuilder = TreeBuilder(numberOfContainers); - tree = treeBuilder.build(); - rootNode = treeBuilder.rootNode; - }); - - test('Testing the traversal of the IntermediateTree', () { - expect(tree.length, treeBuilder.numberOfContainers); - expect(tree.first, rootNode); - }); - - test( - 'Testing [PBIntermediateTree.dist] function, see if it gives the correct distance between two nodes', - () { - var child = tree.firstWhere((node) => node.UUID == 'C_0'); - expect(child, isNotNull); - expect(tree.depthOf(child), 2); - - var parent = tree.firstWhere((node) => node.UUID == 'P_0'); - expect(parent, isNotNull); - expect(tree.depthOf(parent), 1); - - expect(rootNode, isNotNull); - expect(tree.depthOf(rootNode), 0); - }); - }); -} From ec9ecf65324249e14b3cf2d1c9d8d6716d563095 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 12 Aug 2021 21:10:25 -0500 Subject: [PATCH 288/404] Implement `_transformGroup()` method for layout generation service --- .../entities/inherited_scaffold.dart | 3 ++ .../subclasses/pb_intermediate_node.dart | 5 +-- .../helpers/child_strategy.dart | 7 ++-- .../helpers/pb_intermediate_node_tree.dart | 2 + .../pb_layout_generation_service.dart | 39 ++++++++++--------- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index f1a72531..ed7b8995 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -69,16 +69,19 @@ class InheritedScaffold extends PBVisualIntermediateNode // } if (node is InjectedAppbar) { + node.parent = this; children.add(node..attributeName = 'appBar'); // currentContext.canvasFrame = Rectangle.fromPoints( // currentContext.screenFrame.topLeft, node.frame.bottomRight); return; } if (node is InjectedTabBar) { + node.parent = this; children.add(node..attributeName = 'bottomNavigationBar'); // addAttribute(PBAttribute('bottomNavigationBar', attributeNodes: [node])); return; } else { + node.parent = this; children.add(node..attributeName = 'body'); } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 2d890b28..eba42ee0 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -204,9 +204,8 @@ abstract class PBIntermediateNode //extends Iterable /// INFO: there might be a more straight fowards backtracking way of preventing these side effects. void align(PBContext context) { alignStrategy.align(context, this); - for (var att in children ?? []) { - var child = att.attributeNode; - child?.align(context.clone()); + for (var currChild in children ?? []) { + currChild?.align(context.clone()); } } diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index b57234b7..caa3ab34 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -65,8 +65,9 @@ class TempChildrenStrategy extends ChildrenStrategy { @override void addChild(PBIntermediateNode target, children) { - var group = - target.children.firstWhere((element) => element is TempGroupLayoutNode); + var group = target.children.firstWhere( + (element) => element is TempGroupLayoutNode, + orElse: () => null); if (group != null && target.children.length == 1) { group.addChild(children); } else if (target.children.isNotEmpty) { @@ -78,7 +79,7 @@ class TempChildrenStrategy extends ChildrenStrategy { target.children = [temp]; } else if (children is PBIntermediateNode) { children.parent = target; - target.addChild(children); + target.children.add(children); } } } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index fb51c47c..aa8a016d 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -133,6 +133,7 @@ class PBIntermediateTree extends Iterable var grandChilds = parent.children .where((element) => element.UUID == node.UUID) .map((e) => e.children) + ///FIXME: Right now the iterator is returning null insize of a list when iterating the tree. .where((element) => element != null) .expand((element) => element) @@ -162,6 +163,7 @@ class PBIntermediateTree extends Iterable removeNode(target, eliminateSubTree: true); replacement.children.addAll(orphans); parent.children.add(replacement); + replacement.parent = parent; return true; } diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 43b6fac9..c5e744f6 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -79,19 +79,20 @@ class PBLayoutGenerationService extends AITHandler { // ..removeWhere((element) => element == null)) // .first; - tree = _removingMeaninglessGroup(tree); + _removingMeaninglessGroup(tree); + _transformGroup(tree); // tree.rootNode = l.first; - rootNode = _traverseLayersUtil(rootNode, (layer) { - // return layer + // rootNode = _traverseLayersUtil(rootNode, (layer) { + // return layer - // ///Remove the `TempGroupLayout` nodes that only contain one node - // .map(_removingMeaninglessGroup) - // .map((node) => _layoutConditionalReplacement(node, context)) - // .toList() + // ///Remove the `TempGroupLayout` nodes that only contain one node + // .map(_removingMeaninglessGroup) + // .map((node) => _layoutConditionalReplacement(node, context)) + // .toList() - // /// Filter out the elements that are null in the tree - // ..removeWhere((element) => element == null); - }); + // /// Filter out the elements that are null in the tree + // ..removeWhere((element) => element == null); + // }); ///After all the layouts are generated, the [PostConditionRules] are going ///to be applyed to the layerss @@ -154,7 +155,7 @@ class PBLayoutGenerationService extends AITHandler { /// /// Ex: Designer put a group with one child that was a group /// and that group contained the visual nodes. - PBIntermediateTree _removingMeaninglessGroup(PBIntermediateTree tree) { + void _removingMeaninglessGroup(PBIntermediateTree tree) { tree .where( (node) => node is TempGroupLayoutNode && node.children.length <= 1) @@ -172,18 +173,18 @@ class PBLayoutGenerationService extends AITHandler { // constraints: tempGroup.constraints ))); }); - return tree; } /// Transforming the [TempGroupLayoutNode] into regular [PBLayoutIntermediateNode] - PBIntermediateNode _transformGroup(PBIntermediateNode group) { - if (group is TempGroupLayoutNode) { + void _transformGroup(PBIntermediateTree tree) { + tree.whereType().forEach((tempGroup) { var stack = PBIntermediateStackLayout( - name: group.name, constraints: group.constraints); - stack.children.addAll(group.children); - group = stack; - } - return group; + name: tempGroup.name, + constraints: tempGroup.constraints, + ); + stack.children.addAll(tempGroup.children); + tree.replaceNode(tempGroup, stack); + }); } ///If `node` contains a single or multiple [PBIntermediateNode]s From e6acee736de3a3632b78075248f4a8165f76cef2 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 12 Aug 2021 22:17:16 -0600 Subject: [PATCH 289/404] REMOVED dead code --- .../subclasses/pb_intermediate_node.dart | 93 ------------------- 1 file changed, 93 deletions(-) diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index eba42ee0..f75eda46 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -43,27 +43,6 @@ abstract class PBIntermediateNode //extends Iterable @JsonKey(ignore: true) PBIntermediateConstraints constraints; - /// Map representing the attributes of [this]. - /// The key represents the name of the attribute, while the value - /// is a List representing the nodes under - /// that attribute. - // @JsonKey( - // name: 'children', - // fromJson: _childrenFromJson, - // toJson: _childrenToJson, - // nullable: true, - // ) - // List _attributes; - - // // TODO(eddie) this is a work around that is currently being tested, delete afterwards - // @JsonKey(name: 'child', fromJson: _childToJson, nullable: true) - // set _child(PBAttribute attribute) { - // _attributes ??= []; - // _attributes.add(attribute); - // } - - // @JsonKey(ignore: true) - // List get attributes => _attributes; @override @JsonKey(ignore: true) PBIntermediateNode parent; @@ -82,23 +61,6 @@ abstract class PBIntermediateNode //extends Iterable @JsonKey(ignore: true) AlignStrategy alignStrategy = NoAlignment(); - /// Gets the [PBIntermediateNode] at attribute `child` - // PBIntermediateNode get child => getAttributeNamed('child')?.attributeNode; - - /// Sets the `child` attribute's `attributeNode` to `element`. - /// If a `child` attribute does not yet exist, it creates it. - // set child(PBIntermediateNode element) { - // if (element == null) { - // return; - // } - // if (!hasAttribute('child')) { - // addAttribute(PBAttribute('child', attributeNodes: [element])); - // } else { - // getAttributeNamed('child').attributeNode = element; - // } - - // } - @JsonKey( ignore: false, name: 'boundaryRectangle', @@ -106,9 +68,6 @@ abstract class PBIntermediateNode //extends Iterable toJson: DeserializedRectangle.toJson) Rectangle frame; - // @JsonKey(ignore: true) - // PBContext currentContext; - // @JsonKey(ignore: true) // PBGenerationViewData get managerData => currentContext.tree.data; @@ -158,30 +117,6 @@ abstract class PBIntermediateNode //extends Iterable return children.any((element) => element.attributeName == attributeName); } - /// Adds the [PBAttribute] to this node's `attributes` list. - /// When `overwrite` is set to true, if the provided `attribute` has the same - /// name as another attribute in `attributes`, it will replace the old one. - /// Returns true if the addition was successful, false otherwise. - // bool addAttribute(PBAttribute attribute, {bool overwrite = false}) { - // // Iterate through the list of attributes - // for (var i = 0; i < attributes.length; i++) { - // var childAttr = attributes[i]; - - // // If there is a duplicate, replace if `overwrite` is true - // if (childAttr.attributeName == attribute.attributeName) { - // if (overwrite) { - // attributes[i] = attribute; - // return true; - // } - // return false; - // } - // } - - // // Add attribute, no duplicate found - // attributes.add(attribute); - // return true; - // } - /// Adds child to node. void addChild(PBIntermediateNode node) { childrenStrategy.addChild(this, node); @@ -222,34 +157,6 @@ abstract class PBIntermediateNode //extends Iterable } }); } - - // static List _childrenFromJson(Map json) { - // var key = 'children'; - // var children = json[key] as List; - // return [ - // PBAttribute(key, - // attributeNodes: children - // .map((child) => PBIntermediateNode.fromJson(child)) - // .toList()) - // ]; - // } - - // static Map _childrenToJson(List attributes) { - // var mapEntries = attributes - // .map((PBAttribute attribute) => MapEntry( - // attribute.attributeName, - // attribute.attributeNode == null - // ? attribute.attributeNodes.map((e) => e.toJson()).toList() - // : [attribute.attributeNode.toJson()])) - // .toList(); - // return Map.fromEntries(mapEntries); - // } - - // static PBAttribute _childToJson(Map json) { - // var key = 'child'; - // return PBAttribute(key, - // attributeNodes: [PBIntermediateNode.fromJson(json[key])]); - // } } extension PBPointLegacyMethod on Point { From acabb81fa49cbf5d4cd9a953e9d26728fe313e97 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 12 Aug 2021 23:17:22 -0500 Subject: [PATCH 290/404] Fix layout frame issues Fix layout assignment issues --- lib/eggs/custom_egg.dart | 2 +- .../pb_layout_intermediate_node.dart | 14 ++++----- .../helpers/child_strategy.dart | 30 +++++++++++++------ .../pb_layout_generation_service.dart | 2 ++ 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 76fa0671..3d3faefb 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -22,7 +22,7 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { String name, ) : super(UUID, frame, name) { generator = CustomEggGenerator(); - childrenStrategy = OneChildStrategy('child'); + childrenStrategy = TempChildrenStrategy('child'); } @override diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index f4a62128..6e8349b1 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:uuid/uuid.dart'; @@ -34,7 +35,9 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode PBLayoutIntermediateNode(String UUID, Rectangle frame, this._layoutRules, this._exceptions, String name, {this.prototypeNode, PBIntermediateConstraints constraints}) - : super(UUID ?? Uuid().v4(), frame, name, constraints: constraints); + : super(UUID ?? Uuid().v4(), frame, name, constraints: constraints) { + childrenStrategy = MultipleChildStrategy('children'); + } ///Replace the current children with the [children] void replaceChildren(List children, PBContext context) { @@ -56,10 +59,6 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode return false; } - @override - void addChild(PBIntermediateNode node) { - super.addChild(node); - } @override void handleChildren(PBContext context) { @@ -102,9 +101,8 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode } ///Sort children - void sortChildren() => - children.sort((child0, child1) => child0.frame.topLeft - .compareTo(child1.frame.topLeft)); + void sortChildren() => children.sort( + (child0, child1) => child0.frame.topLeft.compareTo(child1.frame.topLeft)); ///The [PBLayoutIntermediateNode] contains a series of rules that determines if the children is part of that layout. All the children ///are going to have to meet the rules that the [PBLayoutIntermediateNode] presents. This method presents a way of comparing two children [PBIntermediateNode] diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index caa3ab34..24edd4c2 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -3,11 +3,11 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:quick_log/quick_log.dart'; abstract class ChildrenStrategy { - Logger log; + Logger logger; final String attributeName; final bool overwridable; ChildrenStrategy(this.attributeName, this.overwridable) { - log = Logger(runtimeType.toString()); + logger = Logger(runtimeType.toString()); } void addChild(PBIntermediateNode target, dynamic children); } @@ -22,7 +22,7 @@ class OneChildStrategy extends ChildrenStrategy { child.parent = target; target.children = [child]; } else { - log.warning( + logger.warning( 'Tried adding ${child.runtimeType.toString()} to ${target.runtimeType.toString()}'); } } @@ -40,9 +40,8 @@ class MultipleChildStrategy extends ChildrenStrategy { return child; })); } else if (children is PBIntermediateNode) { - var node = children; - node.parent = target; - node.children.forEach(target.addChild); + children.parent = target; + target.children.add(children); } } } @@ -53,7 +52,7 @@ class NoChildStrategy extends ChildrenStrategy { @override void addChild(PBIntermediateNode target, children) { if (children != null) { - log.warning( + logger.warning( 'Tried adding ${children.runtimeType.toString()} to ${target.runtimeType.toString()}'); } } @@ -69,13 +68,26 @@ class TempChildrenStrategy extends ChildrenStrategy { (element) => element is TempGroupLayoutNode, orElse: () => null); if (group != null && target.children.length == 1) { + // Calculate new frame based on incoming child + var newFrame = group.frame.boundingBox(children.frame); group.addChild(children); + group.frame = newFrame; } else if (target.children.isNotEmpty) { - var child = target.children.first; var temp = TempGroupLayoutNode(null, null, name: children.name) - ..addChild(child) ..addChild(children) ..parent = target; + // Add target's existing children to temp group layout + target.children.forEach((child) { + temp.addChild(child); + child.parent = temp; + }); + // Calculate bounding box from all children + var frame = temp.children.first.frame; + for (var i = 1; i < temp.children.length; i++) { + frame = frame.boundingBox(temp.children[i].frame); + } + + temp.frame = frame; target.children = [temp]; } else if (children is PBIntermediateNode) { children.parent = target; diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index c5e744f6..e6e89502 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -182,7 +182,9 @@ class PBLayoutGenerationService extends AITHandler { name: tempGroup.name, constraints: tempGroup.constraints, ); + stack.frame = tempGroup.frame; stack.children.addAll(tempGroup.children); + tempGroup.children.forEach((element) => element.parent = stack); tree.replaceNode(tempGroup, stack); }); } From 2c6ccb630a98a04afec4c4d0df293477fd95699e Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 12 Aug 2021 22:18:19 -0600 Subject: [PATCH 291/404] FIXED the handle child method and frame in stack --- .../entities/inherited_shape_group.dart | 7 +++---- lib/interpret_and_optimize/entities/layouts/stack.dart | 5 ++++- lib/main.dart | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index aa8c90e2..5f70f377 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -17,7 +17,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; - +import 'package:path/path.dart' as p; part 'inherited_shape_group.g.dart'; @JsonSerializable() @@ -52,12 +52,11 @@ class InheritedShapeGroup extends PBVisualIntermediateNode childrenStrategy = NoChildStrategy(); ImageReferenceStorage().addReferenceAndWrite( - UUID, '${MainInfo().outputPath}assets/images', image); + UUID, p.join(MainInfo().outputPath, 'assets/images'), image); } static PBIntermediateNode fromJson(Map json) { - var group = _$InheritedShapeGroupFromJson(json) - ..originalRef = json; + var group = _$InheritedShapeGroupFromJson(json)..originalRef = json; group.mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 61a580d4..3a9bd5f6 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -49,7 +49,10 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { /// The width of this stack must be the full width of the Scaffold or Artboard. As discussed, at some point we can change this but for now, this makes the most sense. - var stack = PBIntermediateStackLayout(name: name); + var frame = children.first.frame; + children.forEach((element) => frame.boundingBox(element.frame)); + + var stack = PBIntermediateStackLayout(name: name)..frame = frame; stack.prototypeNode = prototypeNode; children.forEach((child) => stack.addChild(child)); return stack; diff --git a/lib/main.dart b/lib/main.dart index 7bdb6608..61b38b0a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -121,6 +121,7 @@ ${parser.usage} await Future.wait(pbProject.forest.map((tree) { var context = PBContext(processInfo.configuration); + tree.forEach((node) => node.handleChildren(context)); return interpretService .interpretAndOptimize(tree, context, pbProject) .then((tree) => fpb.genAITree(tree, context)); From 41a34806dede45a69a6497fb4610764fa2e9c61b Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 12 Aug 2021 22:18:36 -0600 Subject: [PATCH 292/404] FIX layout generation service --- .../pb_layout_generation_service.dart | 122 +++--------------- 1 file changed, 16 insertions(+), 106 deletions(-) diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index c5e744f6..296c0e27 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -12,6 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:path/path.dart'; import 'package:quick_log/quick_log.dart'; import 'package:tuple/tuple.dart'; @@ -64,45 +65,18 @@ class PBLayoutGenerationService extends AITHandler { return Future.value(tree); } try { - // var removedList = tree.toList() - // ..removeWhere((node) => node is TempGroupLayoutNode); - // tree - // .whereType() - // .forEach((group) => group.parent.children.remove(group)); - // tree.rootNode = removedList.first; - // // tree.forEach((att) => _removingMeaninglessGroup(att.attributeNode)); - // rootNode = (tree - // // .map((node) => _removingMeaninglessGroup(node)) - // .map((node) => _transformGroup(node)) - // .map((node) => _layoutConditionalReplacement(node, context)) - // .toList() - // ..removeWhere((element) => element == null)) - // .first; - _removingMeaninglessGroup(tree); _transformGroup(tree); - // tree.rootNode = l.first; - // rootNode = _traverseLayersUtil(rootNode, (layer) { - // return layer - - // ///Remove the `TempGroupLayout` nodes that only contain one node - // .map(_removingMeaninglessGroup) - // .map((node) => _layoutConditionalReplacement(node, context)) - // .toList() - - // /// Filter out the elements that are null in the tree - // ..removeWhere((element) => element == null); - // }); + _layoutTransformation(tree, context); ///After all the layouts are generated, the [PostConditionRules] are going ///to be applyed to the layerss _applyPostConditionRules(rootNode, context); // return Future.value(tree); - } catch (e, stackTrace) { - MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); + } catch (e) { + MainInfo().captureException( + e, + ); logger.error(e.toString()); } finally { tree.rootNode = rootNode; @@ -110,47 +84,6 @@ class PBLayoutGenerationService extends AITHandler { } } - PBIntermediateNode _traverseLayersUtil( - PBIntermediateNode rootNode, - List Function(List layer) - transformation) { - ///The stack is going to saving the current layer of tree along with the parent of - ///the layer. It makes use of a `Tuple2()` to save the parent in the first index and a list - ///of nodes for the current layer in the second layer. - var stack = >>[]; - stack.add(Tuple2(null, [rootNode])); - - while (stack.isNotEmpty) { - var currentTuple = stack.removeLast(); - var children = currentTuple.item2; - var node = currentTuple.item1; - - stack.add(Tuple2(node, node.children)); - node.children = transformation(node.children); - children.forEach((child) { - // child = transformation(child); - - // child?.attributeNodes?.forEach((currentNode) { - // currentNode?.attributes?.forEach((attribute) { - // stack.add(Tuple2(currentNode, [ - // // currentNode. - // ])); - // }); - // }); - }); - if (node != null) { - currentTuple.item2.forEach((attribute) { - // node.addAttribute(attribute, overwrite: true); - }); - } else { - ///if the `currentTuple.item1` is null, that implies the `currentTuple.item2.first` is the - ///new `rootNode`. - // rootNode = currentTuple.item2.first.attributeNode; - } - } - return rootNode; - } - /// If this node is an unecessary [TempGroupLayoutNode], from the [tree] /// /// Ex: Designer put a group with one child that was a group @@ -187,24 +120,13 @@ class PBLayoutGenerationService extends AITHandler { }); } - ///If `node` contains a single or multiple [PBIntermediateNode]s - bool _containsChildren(PBIntermediateNode node) => - (node is PBVisualIntermediateNode && node.child != null) || - (node is PBLayoutIntermediateNode && node.children.isNotEmpty); - - ///Each of the [TempGroupLayoutNode] could derive multiple [IntermediateLayoutNode]s because - ///nodes should be considered into subsections. For example, if child 0 and child 1 statisfy the - ///rule of a [Row] but not child 3, then child 0 and child 1 should be placed inside of a [Row]. Therefore, - ///there could be many[IntermediateLayoutNodes] derived in the children level of the `group`. - PBIntermediateNode _layoutConditionalReplacement( - PBIntermediateNode parent, PBContext context, - {depth = 1}) { - if (parent is PBLayoutIntermediateNode && depth >= 0) { - parent.sortChildren(); + void _layoutTransformation(PBIntermediateTree tree, PBContext context) { + for (var parent in tree) { var children = parent.children; + children.sort((n0, n1) => n0.frame.topLeft.compareTo(n1.frame.topLeft)); + var childPointer = 0; var reCheck = false; - while (childPointer < children.length - 1) { var currentNode = children[childPointer]; var nextNode = children[childPointer + 1]; @@ -217,14 +139,16 @@ class PBLayoutGenerationService extends AITHandler { ///If either `currentNode` or `nextNode` is of the same `runtimeType` as the satified [PBLayoutIntermediateNode], ///then its going to use either one instead of creating a new [PBLayoutIntermediateNode]. if (layout.runtimeType == currentNode.runtimeType) { + tree.removeNode(nextNode, eliminateSubTree: true); currentNode.addChild(nextNode); - currentNode = _layoutConditionalReplacement(currentNode, context, - depth: depth - 1); + // tree.replaceNode(nextNode, currentNode..addChild(nextNode)); + generatedLayout = currentNode; } else if (layout.runtimeType == nextNode.runtimeType) { + tree.removeNode(currentNode, eliminateSubTree: true); nextNode.addChild(currentNode); - nextNode = _layoutConditionalReplacement(nextNode, context, - depth: depth - 1); + // tree.replaceNode(currentNode, nextNode..addChild(currentNode)); + generatedLayout = nextNode; } @@ -246,21 +170,7 @@ class PBLayoutGenerationService extends AITHandler { childPointer = reCheck ? 0 : childPointer + 1; reCheck = false; } - parent.replaceChildren(children, context); - if (children.length == 1) { - /// With the support for scaling & pinning, Stacks are now responsible for positioning. - if (parent is PBIntermediateStackLayout) { - return parent; - } - return _replaceNode(parent, children[0]); - } else { - return parent is! TempGroupLayoutNode - ? parent - : _replaceNode(parent, - _defaultLayout.generateLayout(children, context, parent.name)); - } } - return parent; } ///Makes sure all the necessary attributes are recovered before replacing a [PBIntermediateNode] From be408e4f807a5d7567ad082cb14cf11d9036dbef Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 12 Aug 2021 22:19:33 -0600 Subject: [PATCH 293/404] Merge branch 'merge/gen-bug' --- .../entities/inherited_shape_group.dart | 7 +- .../entities/layouts/stack.dart | 5 +- .../subclasses/pb_intermediate_node.dart | 93 ------------- .../pb_layout_generation_service.dart | 122 +++--------------- lib/main.dart | 1 + 5 files changed, 24 insertions(+), 204 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index aa8c90e2..5f70f377 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -17,7 +17,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; - +import 'package:path/path.dart' as p; part 'inherited_shape_group.g.dart'; @JsonSerializable() @@ -52,12 +52,11 @@ class InheritedShapeGroup extends PBVisualIntermediateNode childrenStrategy = NoChildStrategy(); ImageReferenceStorage().addReferenceAndWrite( - UUID, '${MainInfo().outputPath}assets/images', image); + UUID, p.join(MainInfo().outputPath, 'assets/images'), image); } static PBIntermediateNode fromJson(Map json) { - var group = _$InheritedShapeGroupFromJson(json) - ..originalRef = json; + var group = _$InheritedShapeGroupFromJson(json)..originalRef = json; group.mapRawChildren(json); diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 61a580d4..3a9bd5f6 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -49,7 +49,10 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { /// The width of this stack must be the full width of the Scaffold or Artboard. As discussed, at some point we can change this but for now, this makes the most sense. - var stack = PBIntermediateStackLayout(name: name); + var frame = children.first.frame; + children.forEach((element) => frame.boundingBox(element.frame)); + + var stack = PBIntermediateStackLayout(name: name)..frame = frame; stack.prototypeNode = prototypeNode; children.forEach((child) => stack.addChild(child)); return stack; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index eba42ee0..f75eda46 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -43,27 +43,6 @@ abstract class PBIntermediateNode //extends Iterable @JsonKey(ignore: true) PBIntermediateConstraints constraints; - /// Map representing the attributes of [this]. - /// The key represents the name of the attribute, while the value - /// is a List representing the nodes under - /// that attribute. - // @JsonKey( - // name: 'children', - // fromJson: _childrenFromJson, - // toJson: _childrenToJson, - // nullable: true, - // ) - // List _attributes; - - // // TODO(eddie) this is a work around that is currently being tested, delete afterwards - // @JsonKey(name: 'child', fromJson: _childToJson, nullable: true) - // set _child(PBAttribute attribute) { - // _attributes ??= []; - // _attributes.add(attribute); - // } - - // @JsonKey(ignore: true) - // List get attributes => _attributes; @override @JsonKey(ignore: true) PBIntermediateNode parent; @@ -82,23 +61,6 @@ abstract class PBIntermediateNode //extends Iterable @JsonKey(ignore: true) AlignStrategy alignStrategy = NoAlignment(); - /// Gets the [PBIntermediateNode] at attribute `child` - // PBIntermediateNode get child => getAttributeNamed('child')?.attributeNode; - - /// Sets the `child` attribute's `attributeNode` to `element`. - /// If a `child` attribute does not yet exist, it creates it. - // set child(PBIntermediateNode element) { - // if (element == null) { - // return; - // } - // if (!hasAttribute('child')) { - // addAttribute(PBAttribute('child', attributeNodes: [element])); - // } else { - // getAttributeNamed('child').attributeNode = element; - // } - - // } - @JsonKey( ignore: false, name: 'boundaryRectangle', @@ -106,9 +68,6 @@ abstract class PBIntermediateNode //extends Iterable toJson: DeserializedRectangle.toJson) Rectangle frame; - // @JsonKey(ignore: true) - // PBContext currentContext; - // @JsonKey(ignore: true) // PBGenerationViewData get managerData => currentContext.tree.data; @@ -158,30 +117,6 @@ abstract class PBIntermediateNode //extends Iterable return children.any((element) => element.attributeName == attributeName); } - /// Adds the [PBAttribute] to this node's `attributes` list. - /// When `overwrite` is set to true, if the provided `attribute` has the same - /// name as another attribute in `attributes`, it will replace the old one. - /// Returns true if the addition was successful, false otherwise. - // bool addAttribute(PBAttribute attribute, {bool overwrite = false}) { - // // Iterate through the list of attributes - // for (var i = 0; i < attributes.length; i++) { - // var childAttr = attributes[i]; - - // // If there is a duplicate, replace if `overwrite` is true - // if (childAttr.attributeName == attribute.attributeName) { - // if (overwrite) { - // attributes[i] = attribute; - // return true; - // } - // return false; - // } - // } - - // // Add attribute, no duplicate found - // attributes.add(attribute); - // return true; - // } - /// Adds child to node. void addChild(PBIntermediateNode node) { childrenStrategy.addChild(this, node); @@ -222,34 +157,6 @@ abstract class PBIntermediateNode //extends Iterable } }); } - - // static List _childrenFromJson(Map json) { - // var key = 'children'; - // var children = json[key] as List; - // return [ - // PBAttribute(key, - // attributeNodes: children - // .map((child) => PBIntermediateNode.fromJson(child)) - // .toList()) - // ]; - // } - - // static Map _childrenToJson(List attributes) { - // var mapEntries = attributes - // .map((PBAttribute attribute) => MapEntry( - // attribute.attributeName, - // attribute.attributeNode == null - // ? attribute.attributeNodes.map((e) => e.toJson()).toList() - // : [attribute.attributeNode.toJson()])) - // .toList(); - // return Map.fromEntries(mapEntries); - // } - - // static PBAttribute _childToJson(Map json) { - // var key = 'child'; - // return PBAttribute(key, - // attributeNodes: [PBIntermediateNode.fromJson(json[key])]); - // } } extension PBPointLegacyMethod on Point { diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index c5e744f6..296c0e27 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -12,6 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:path/path.dart'; import 'package:quick_log/quick_log.dart'; import 'package:tuple/tuple.dart'; @@ -64,45 +65,18 @@ class PBLayoutGenerationService extends AITHandler { return Future.value(tree); } try { - // var removedList = tree.toList() - // ..removeWhere((node) => node is TempGroupLayoutNode); - // tree - // .whereType() - // .forEach((group) => group.parent.children.remove(group)); - // tree.rootNode = removedList.first; - // // tree.forEach((att) => _removingMeaninglessGroup(att.attributeNode)); - // rootNode = (tree - // // .map((node) => _removingMeaninglessGroup(node)) - // .map((node) => _transformGroup(node)) - // .map((node) => _layoutConditionalReplacement(node, context)) - // .toList() - // ..removeWhere((element) => element == null)) - // .first; - _removingMeaninglessGroup(tree); _transformGroup(tree); - // tree.rootNode = l.first; - // rootNode = _traverseLayersUtil(rootNode, (layer) { - // return layer - - // ///Remove the `TempGroupLayout` nodes that only contain one node - // .map(_removingMeaninglessGroup) - // .map((node) => _layoutConditionalReplacement(node, context)) - // .toList() - - // /// Filter out the elements that are null in the tree - // ..removeWhere((element) => element == null); - // }); + _layoutTransformation(tree, context); ///After all the layouts are generated, the [PostConditionRules] are going ///to be applyed to the layerss _applyPostConditionRules(rootNode, context); // return Future.value(tree); - } catch (e, stackTrace) { - MainInfo().sentry.captureException( - exception: e, - stackTrace: stackTrace, - ); + } catch (e) { + MainInfo().captureException( + e, + ); logger.error(e.toString()); } finally { tree.rootNode = rootNode; @@ -110,47 +84,6 @@ class PBLayoutGenerationService extends AITHandler { } } - PBIntermediateNode _traverseLayersUtil( - PBIntermediateNode rootNode, - List Function(List layer) - transformation) { - ///The stack is going to saving the current layer of tree along with the parent of - ///the layer. It makes use of a `Tuple2()` to save the parent in the first index and a list - ///of nodes for the current layer in the second layer. - var stack = >>[]; - stack.add(Tuple2(null, [rootNode])); - - while (stack.isNotEmpty) { - var currentTuple = stack.removeLast(); - var children = currentTuple.item2; - var node = currentTuple.item1; - - stack.add(Tuple2(node, node.children)); - node.children = transformation(node.children); - children.forEach((child) { - // child = transformation(child); - - // child?.attributeNodes?.forEach((currentNode) { - // currentNode?.attributes?.forEach((attribute) { - // stack.add(Tuple2(currentNode, [ - // // currentNode. - // ])); - // }); - // }); - }); - if (node != null) { - currentTuple.item2.forEach((attribute) { - // node.addAttribute(attribute, overwrite: true); - }); - } else { - ///if the `currentTuple.item1` is null, that implies the `currentTuple.item2.first` is the - ///new `rootNode`. - // rootNode = currentTuple.item2.first.attributeNode; - } - } - return rootNode; - } - /// If this node is an unecessary [TempGroupLayoutNode], from the [tree] /// /// Ex: Designer put a group with one child that was a group @@ -187,24 +120,13 @@ class PBLayoutGenerationService extends AITHandler { }); } - ///If `node` contains a single or multiple [PBIntermediateNode]s - bool _containsChildren(PBIntermediateNode node) => - (node is PBVisualIntermediateNode && node.child != null) || - (node is PBLayoutIntermediateNode && node.children.isNotEmpty); - - ///Each of the [TempGroupLayoutNode] could derive multiple [IntermediateLayoutNode]s because - ///nodes should be considered into subsections. For example, if child 0 and child 1 statisfy the - ///rule of a [Row] but not child 3, then child 0 and child 1 should be placed inside of a [Row]. Therefore, - ///there could be many[IntermediateLayoutNodes] derived in the children level of the `group`. - PBIntermediateNode _layoutConditionalReplacement( - PBIntermediateNode parent, PBContext context, - {depth = 1}) { - if (parent is PBLayoutIntermediateNode && depth >= 0) { - parent.sortChildren(); + void _layoutTransformation(PBIntermediateTree tree, PBContext context) { + for (var parent in tree) { var children = parent.children; + children.sort((n0, n1) => n0.frame.topLeft.compareTo(n1.frame.topLeft)); + var childPointer = 0; var reCheck = false; - while (childPointer < children.length - 1) { var currentNode = children[childPointer]; var nextNode = children[childPointer + 1]; @@ -217,14 +139,16 @@ class PBLayoutGenerationService extends AITHandler { ///If either `currentNode` or `nextNode` is of the same `runtimeType` as the satified [PBLayoutIntermediateNode], ///then its going to use either one instead of creating a new [PBLayoutIntermediateNode]. if (layout.runtimeType == currentNode.runtimeType) { + tree.removeNode(nextNode, eliminateSubTree: true); currentNode.addChild(nextNode); - currentNode = _layoutConditionalReplacement(currentNode, context, - depth: depth - 1); + // tree.replaceNode(nextNode, currentNode..addChild(nextNode)); + generatedLayout = currentNode; } else if (layout.runtimeType == nextNode.runtimeType) { + tree.removeNode(currentNode, eliminateSubTree: true); nextNode.addChild(currentNode); - nextNode = _layoutConditionalReplacement(nextNode, context, - depth: depth - 1); + // tree.replaceNode(currentNode, nextNode..addChild(currentNode)); + generatedLayout = nextNode; } @@ -246,21 +170,7 @@ class PBLayoutGenerationService extends AITHandler { childPointer = reCheck ? 0 : childPointer + 1; reCheck = false; } - parent.replaceChildren(children, context); - if (children.length == 1) { - /// With the support for scaling & pinning, Stacks are now responsible for positioning. - if (parent is PBIntermediateStackLayout) { - return parent; - } - return _replaceNode(parent, children[0]); - } else { - return parent is! TempGroupLayoutNode - ? parent - : _replaceNode(parent, - _defaultLayout.generateLayout(children, context, parent.name)); - } } - return parent; } ///Makes sure all the necessary attributes are recovered before replacing a [PBIntermediateNode] diff --git a/lib/main.dart b/lib/main.dart index 7bdb6608..61b38b0a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -121,6 +121,7 @@ ${parser.usage} await Future.wait(pbProject.forest.map((tree) { var context = PBContext(processInfo.configuration); + tree.forEach((node) => node.handleChildren(context)); return interpretService .interpretAndOptimize(tree, context, pbProject) .then((tree) => fpb.genAITree(tree, context)); From 697772e7f1c5fa71ba68a3481bf242eaa1fdd207 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Fri, 13 Aug 2021 12:24:04 -0500 Subject: [PATCH 294/404] Fix layout service and alignment service issues --- .../entities/inherited_scaffold.dart | 20 ++++++------------- .../pb_layout_intermediate_node.dart | 2 +- .../helpers/align_strategy.dart | 1 + .../pb_layout_generation_service.dart | 6 ++++-- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index ed7b8995..7ead2f11 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -116,25 +116,17 @@ class InheritedScaffold extends PBVisualIntermediateNode @override void handleChildren(PBContext context) { var children = getAllAtrributeNamed('body'); - var groupAtt = TempGroupLayoutNode(null, null)..attributeName = 'body'; + var groupAtt = TempGroupLayoutNode(null, null) + ..attributeName = 'body' + ..parent = this; children.forEach((att) => groupAtt.addChild(att)); - children = [groupAtt]; + // Top-most stack should have scaffold's frame to align children properly + groupAtt.frame = frame; - ///get tempgroup - ///add all of the rest of children to it - ///if temp group is null, create group - ///add all of the rest of children + this.children = [groupAtt]; } - // @override - // @JsonKey(ignore: true) - // PBIntermediateNode get child => getAttributeNamed('body')?.attributeNode; - - // @JsonKey(ignore: true) - // @override - // List get children => [child, navbar, tabbar]; - List layoutInstruction(List layer) { return layer; } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index 6e8349b1..e9c719e3 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -42,6 +42,7 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode ///Replace the current children with the [children] void replaceChildren(List children, PBContext context) { if (children.isNotEmpty) { + this.children = children; resize(context); } else { logger.warning( @@ -59,7 +60,6 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode return false; } - @override void handleChildren(PBContext context) { resize(context); diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index cbc09a40..3ea0cfeb 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -94,6 +94,7 @@ class PositionedAlignment extends AlignStrategy { right: node.frame.bottomRight.x - child.frame.bottomRight.x, width: child.frame.width, height: child.frame.height)) + ..parent = child.parent ..addChild(child)); }); node.replaceChildren(alignedChildren, context); diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index efb53658..061bd5a8 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -114,8 +114,10 @@ class PBLayoutGenerationService extends AITHandler { var stack = PBIntermediateStackLayout( name: tempGroup.name, constraints: tempGroup.constraints, - ); - stack.frame = tempGroup.frame; + ) + ..frame = tempGroup.frame + ..parent = tempGroup.parent + ..attributeName = tempGroup.attributeName; stack.children.addAll(tempGroup.children); tempGroup.children.forEach((element) => element.parent = stack); tree.replaceNode(tempGroup, stack); From ac02a4882b2dc602dbe05450f9cc9a31e4307bf6 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Fri, 13 Aug 2021 13:23:16 -0500 Subject: [PATCH 295/404] Fix issues with appbar and tabbar not retaining children Fix issues with scaffold not keeping appbar and tabbar --- lib/eggs/injected_app_bar.dart | 12 ++++++++++-- lib/eggs/injected_tab_bar.dart | 6 +++++- .../entities/inherited_scaffold.dart | 11 +++++++---- .../services/pb_layout_generation_service.dart | 4 +++- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 8e6e503d..05c512e2 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -47,12 +47,16 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { } @override - PBEgg generatePluginNode(Rectangle frame, originalRef) { - return InjectedAppbar( + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + var appbar = InjectedAppbar( UUID, frame, originalRef.name, ); + + originalRef.children.forEach(addChild); + + return appbar; } @override @@ -67,6 +71,10 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { class CustomAppBarAlignment extends AlignStrategy { @override void align(PBContext context, InjectedAppbar node) { + if (node.middleItem == null) { + return; + } + /// This align only modifies middleItem var tempNode = InjectedContainer( node.middleItem.UUID, diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 92a4796f..eb2dcbaf 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -49,11 +49,15 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { - return InjectedTabBar( + var tabbar = InjectedTabBar( UUID, frame, originalRef.name, ); + + originalRef.children.forEach(addChild); + + return tabbar; } @override diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 7ead2f11..186617b4 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -116,15 +116,18 @@ class InheritedScaffold extends PBVisualIntermediateNode @override void handleChildren(PBContext context) { var children = getAllAtrributeNamed('body'); - var groupAtt = TempGroupLayoutNode(null, null) + // Top-most stack should have scaffold's frame to align children properly + var groupAtt = TempGroupLayoutNode(null, frame) ..attributeName = 'body' ..parent = this; children.forEach((att) => groupAtt.addChild(att)); - // Top-most stack should have scaffold's frame to align children properly - groupAtt.frame = frame; + // Keep appbar and tabbar + var appBar = getAttributeNamed('appBar'); + var tabBar = getAttributeNamed('bottomNavigationBar'); - this.children = [groupAtt]; + this.children = [groupAtt, appBar, tabBar] + ..removeWhere((element) => element == null); } List layoutInstruction(List layer) { diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 061bd5a8..dbe8959c 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -148,7 +148,9 @@ class PBLayoutGenerationService extends AITHandler { // tree.replaceNode(nextNode, currentNode..addChild(nextNode)); generatedLayout = currentNode; - } else if (layout.runtimeType == nextNode.runtimeType) { + } + //! This is causing appbar to be removed from scaffold and placed inside scaffold's `body` stack + else if (layout.runtimeType == nextNode.runtimeType) { tree.removeNode(currentNode, eliminateSubTree: true); nextNode.addChild(currentNode); // tree.replaceNode(currentNode, nextNode..addChild(currentNode)); From 44b8bee65d44cd3a8f541d17dd740f67a62c4a1b Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 13 Aug 2021 12:27:04 -0600 Subject: [PATCH 296/404] FIX assigned parents to children being removed from a particular node and fixed _transformGroup method --- .../entities/inherited_scaffold.dart | 7 +-- .../helpers/pb_intermediate_node_tree.dart | 5 +- .../pb_layout_generation_service.dart | 54 ++++++++----------- 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index ed7b8995..f175a377 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -119,12 +119,7 @@ class InheritedScaffold extends PBVisualIntermediateNode var groupAtt = TempGroupLayoutNode(null, null)..attributeName = 'body'; children.forEach((att) => groupAtt.addChild(att)); - children = [groupAtt]; - - ///get tempgroup - ///add all of the rest of children to it - ///if temp group is null, create group - ///add all of the rest of children + this.children = [groupAtt]; } // @override diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index aa8a016d..53492db0 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -158,7 +158,10 @@ class PBIntermediateTree extends Iterable var parent = target.parent; var orphans = []; if (acceptChildren) { - orphans.addAll(target.children); + orphans.addAll(target.children.map((e) { + e.parent = parent; + return e; + })); } removeNode(target, eliminateSubTree: true); replacement.children.addAll(orphans); diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index efb53658..b0d8f235 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -111,14 +111,18 @@ class PBLayoutGenerationService extends AITHandler { /// Transforming the [TempGroupLayoutNode] into regular [PBLayoutIntermediateNode] void _transformGroup(PBIntermediateTree tree) { tree.whereType().forEach((tempGroup) { - var stack = PBIntermediateStackLayout( - name: tempGroup.name, - constraints: tempGroup.constraints, - ); - stack.frame = tempGroup.frame; - stack.children.addAll(tempGroup.children); - tempGroup.children.forEach((element) => element.parent = stack); - tree.replaceNode(tempGroup, stack); + // var stack = ; + // stack.frame = tempGroup.frame; + // stack.children.addAll(tempGroup.children); + // tempGroup.children.forEach((element) => element.parent = stack); + // tree.replaceNode(tempGroup, stack); + tree.replaceNode( + tempGroup, + PBIntermediateStackLayout( + name: tempGroup.name, + constraints: tempGroup.constraints, + )..frame = tempGroup.frame, + acceptChildren: true); }); } @@ -136,35 +140,23 @@ class PBLayoutGenerationService extends AITHandler { for (var layout in _availableLayouts) { if (layout.satisfyRules(currentNode, nextNode) && layout.runtimeType != parent.runtimeType) { - var generatedLayout; - ///If either `currentNode` or `nextNode` is of the same `runtimeType` as the satified [PBLayoutIntermediateNode], ///then its going to use either one instead of creating a new [PBLayoutIntermediateNode]. if (layout.runtimeType == currentNode.runtimeType) { - tree.removeNode(nextNode, eliminateSubTree: true); - currentNode.addChild(nextNode); - // tree.replaceNode(nextNode, currentNode..addChild(nextNode)); - - generatedLayout = currentNode; + tree.replaceNode(nextNode, currentNode..addChild(nextNode)); } else if (layout.runtimeType == nextNode.runtimeType) { + tree.replaceNode(currentNode, nextNode..addChild(currentNode)); + } else { + ///If neither of the current nodes are of the same `runtimeType` as the layout, we are going to use the actual + ///satified [PBLayoutIntermediateNode] to generate the layout. We place both of the nodes inside + ///of the generated layout. tree.removeNode(currentNode, eliminateSubTree: true); - nextNode.addChild(currentNode); - // tree.replaceNode(currentNode, nextNode..addChild(currentNode)); - - generatedLayout = nextNode; + tree.removeNode(nextNode, eliminateSubTree: true); + parent.addChild(layout.generateLayout( + [currentNode, nextNode], + context, + '${currentNode.name}${nextNode.name}${layout.runtimeType}')); } - - ///If neither of the current nodes are of the same `runtimeType` as the layout, we are going to use the actual - ///satified [PBLayoutIntermediateNode] to generate the layout. We place both of the nodes inside - ///of the generated layout. - generatedLayout ??= - layout.generateLayout([currentNode, nextNode], context, ''); - var start = childPointer, end = childPointer + 2; - children.replaceRange( - start, - (end > children.length ? children.length : end), - [generatedLayout]); - childPointer = 0; reCheck = true; break; } From dc51602cb81cc7ddda931dd042d0844c036c03e8 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 13 Aug 2021 16:48:30 -0600 Subject: [PATCH 297/404] FIX layout bug causing an infitate loop when two nodes being replaced in the tree where under the same parent --- .../subclasses/pb_intermediate_node.dart | 7 ++-- .../pb_layout_intermediate_node.dart | 35 ++++++++++--------- .../helpers/pb_intermediate_node_tree.dart | 19 ++++++---- .../pb_layout_generation_service.dart | 11 +++--- 4 files changed, 39 insertions(+), 33 deletions(-) diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index f75eda46..5e5ca683 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -23,7 +23,8 @@ part 'pb_intermediate_node.g.dart'; @JsonSerializable( explicitToJson: true, createFactory: false, ignoreUnannotated: true) abstract class PBIntermediateNode //extends Iterable - implements TraversableNode { + implements + TraversableNode { @JsonKey(ignore: true) Logger logger; @@ -54,7 +55,6 @@ abstract class PBIntermediateNode //extends Iterable @JsonKey(ignore: true) PBIntermediateNode get child => children.isEmpty ? null : children.first; - @JsonKey(ignore: true) ChildrenStrategy childrenStrategy = OneChildStrategy('child'); @@ -125,6 +125,9 @@ abstract class PBIntermediateNode //extends Iterable /// constrains could be inherited to that section of the sub-tree. } + @override + int get hashCode => UUID.hashCode; + void handleChildren(PBContext context) {} /// In a recursive manner align the current [this] and the [children] of [this] diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index e9c719e3..3e72763b 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -50,6 +50,12 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode } } + // @override + // void addChild(node){ + // resize(context) + // super.addChild(node); + // } + /// Replace the child at `index` for `replacement`. /// Returns true if the replacement wsa succesful, false otherwise. bool replaceChildAt(int index, PBIntermediateNode replacement) { @@ -66,29 +72,24 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode super.handleChildren(context); } - ///Add node to child - // void addChildToLayout(PBIntermediateNode node) { - // getAttributeNamed('children').attributeNodes.add(node); - // resize(); - // } - void resize(PBContext context) { if (children.isEmpty) { logger .warning('There should be children in the layout so it can resize.'); return; } - var minX = (children[0]).frame.topLeft.x, - minY = (children[0]).frame.topLeft.y, - maxX = (children[0]).frame.bottomRight.x, - maxY = (children[0]).frame.bottomRight.y; - for (var child in children) { - minX = min((child).frame.topLeft.x, minX); - minY = min((child).frame.topLeft.y, minY); - maxX = max((child).frame.bottomRight.x, maxX); - maxY = max((child).frame.bottomRight.y, maxY); - } - frame = Rectangle.fromPoints(Point(minX, minY), Point(maxX, maxY)); + // var minX = (children[0]).frame.topLeft.x, + // minY = (children[0]).frame.topLeft.y, + // maxX = (children[0]).frame.bottomRight.x, + // maxY = (children[0]).frame.bottomRight.y; + // for (var child in children) { + // minX = min((child).frame.topLeft.x, minX); + // minY = min((child).frame.topLeft.y, minY); + // maxX = max((child).frame.bottomRight.x, maxX); + // maxY = max((child).frame.bottomRight.y, maxY); + // } + children.forEach((child) => frame = frame.boundingBox(child.frame)); + // frame = Rectangle.fromPoints(Point(minX, minY), Point(maxX, maxY)); } ///Remove Child diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 53492db0..9a76099c 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -152,21 +152,26 @@ class PBIntermediateTree extends Iterable {bool acceptChildren = false}) { if (target.parent == null) { ///TODO: throw correct error/log - return false; + throw Error(); } var parent = target.parent; - var orphans = []; if (acceptChildren) { - orphans.addAll(target.children.map((e) { - e.parent = parent; + replacement.children.addAll(target.children.map((e) { + e.parent = replacement; return e; })); } removeNode(target, eliminateSubTree: true); - replacement.children.addAll(orphans); - parent.children.add(replacement); - replacement.parent = parent; + replacement.attributeName = target.attributeName; + + /// This conditional is for scenarios where both the [target] and the [replacement] are + /// under the same [parent] + if (!parent.children.contains(replacement)) { + parent.children.add(replacement); + replacement.parent = parent; + } + return true; } diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index b1250120..d7e9f2d9 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -111,11 +111,6 @@ class PBLayoutGenerationService extends AITHandler { /// Transforming the [TempGroupLayoutNode] into regular [PBLayoutIntermediateNode] void _transformGroup(PBIntermediateTree tree) { tree.whereType().forEach((tempGroup) { - // var stack = ; - // stack.frame = tempGroup.frame; - // stack.children.addAll(tempGroup.children); - // tempGroup.children.forEach((element) => element.parent = stack); - // tree.replaceNode(tempGroup, stack); tree.replaceNode( tempGroup, PBIntermediateStackLayout( @@ -143,12 +138,14 @@ class PBLayoutGenerationService extends AITHandler { ///If either `currentNode` or `nextNode` is of the same `runtimeType` as the satified [PBLayoutIntermediateNode], ///then its going to use either one instead of creating a new [PBLayoutIntermediateNode]. if (layout.runtimeType == currentNode.runtimeType) { - tree.replaceNode(nextNode, currentNode..addChild(nextNode)); + tree.replaceNode(nextNode, currentNode); + currentNode.addChild(nextNode); } //! This is causing appbar to be removed from scaffold and placed inside scaffold's `body` stack else if (layout.runtimeType == nextNode.runtimeType) { - tree.replaceNode(currentNode, nextNode..addChild(currentNode)); + tree.replaceNode(currentNode, nextNode); + nextNode.addChild(currentNode); } else { ///If neither of the current nodes are of the same `runtimeType` as the layout, we are going to use the actual ///satified [PBLayoutIntermediateNode] to generate the layout. We place both of the nodes inside From 5058d0bdf6b8367d5c1a027ad0f79549df96f7f4 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 13 Aug 2021 22:26:45 -0600 Subject: [PATCH 298/404] FIX the mixup of diff attribute name nodes in the layout service (causing in one example the appbar to be treated as a body element) --- .../services/pb_layout_generation_service.dart | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index d7e9f2d9..3ca6fc59 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -133,6 +133,12 @@ class PBLayoutGenerationService extends AITHandler { var nextNode = children[childPointer + 1]; for (var layout in _availableLayouts) { + /// This conditional statement is to not mixup the elements that pertain to different [currentNode.attributeName]. + /// For example, if [currentNode.attributeName] is an `appBar` and [nextNode.attributeName] is a `stack`, + /// then you would not generate a [PBLayoutIntermediateNode] to encapsulate them both. + if (currentNode.attributeName != nextNode.attributeName) { + break; + } if (layout.satisfyRules(currentNode, nextNode) && layout.runtimeType != parent.runtimeType) { ///If either `currentNode` or `nextNode` is of the same `runtimeType` as the satified [PBLayoutIntermediateNode], @@ -140,10 +146,7 @@ class PBLayoutGenerationService extends AITHandler { if (layout.runtimeType == currentNode.runtimeType) { tree.replaceNode(nextNode, currentNode); currentNode.addChild(nextNode); - } - //! This is causing appbar to be removed from scaffold and placed inside scaffold's `body` stack - - else if (layout.runtimeType == nextNode.runtimeType) { + } else if (layout.runtimeType == nextNode.runtimeType) { tree.replaceNode(currentNode, nextNode); nextNode.addChild(currentNode); } else { From ca0cf5928ed7b1bbe5cd34cfa4c21a71ead3b028 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sat, 14 Aug 2021 01:47:17 -0600 Subject: [PATCH 299/404] WIP fixing dependencies between trees --- lib/controllers/interpret.dart | 17 ++++------ lib/eggs/custom_egg.dart | 2 +- lib/eggs/injected_app_bar.dart | 2 +- lib/eggs/injected_tab.dart | 2 +- lib/eggs/injected_tab_bar.dart | 2 +- .../pb_prototype_aggregation_service.dart | 33 ++++++++----------- .../subclasses/pb_intermediate_node.dart | 11 +++++-- .../helpers/element_storage.dart | 18 ++++++++++ .../pb_shared_aggregation_service.dart | 10 ++++-- .../services/pb_symbol_linker_service.dart | 5 +-- lib/main.dart | 9 +++++ .../intermediate_tree_test.dart | 2 +- 12 files changed, 73 insertions(+), 40 deletions(-) create mode 100644 lib/interpret_and_optimize/helpers/element_storage.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 7a43ff2b..5cbc94b0 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -54,20 +55,16 @@ class Interpret { handlers ??= aitHandlers; aitServiceBuilder ??= AITServiceBuilder(aitHandlers); + var elementStorage = ElementStorage(); /// This is a workaround for adding missing information to either the [PBContext] or any of the /// [PBIntermediateNode]s. aitServiceBuilder.addTransformation( - (PBContext context, PBIntermediateTree tree) { - context.project = project; - - /// Assuming that the [tree.rootNode] has the dimensions of the screen. - context.screenFrame = Rectangle.fromPoints( - tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); - context.tree = tree; - tree.context = context; - return Future.value(tree); - }, index: 0, id: 'Assigning $PBContext to $PBIntermediateTree'); + (PBContext context, PBIntermediateNode node, PBIntermediateTree tree) { + elementStorage.treeUUIDs[tree.UUID] = tree; + elementStorage.elementToTree[node.UUID] = tree.UUID; + return Future.value(node); + }, index: 0, id: 'Indexing ${tree.name}'); // await PBPrototypeAggregationService().linkDanglingPrototypeNodes(); diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 3d3faefb..942fd370 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -32,7 +32,7 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { - var egg = CustomEgg(originalRef.name, frame, + var egg = CustomEgg(originalRef.UUID, frame, originalRef.name.replaceAll('', '').pascalCase); originalRef.children.forEach((child) => egg.addChild(child)); return egg; diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 05c512e2..87412348 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -49,7 +49,7 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { var appbar = InjectedAppbar( - UUID, + originalRef.UUID, frame, originalRef.name, ); diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 2673abac..6af2f967 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -37,7 +37,7 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode) { if (originalNode is PBInheritedIntermediate) { var tab = Tab( - UUID, + originalNode.UUID, frame, originalNode.name, prototypeNode: (originalNode as PBInheritedIntermediate).prototypeNode, diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index eb2dcbaf..56839ee7 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -50,7 +50,7 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { var tabbar = InjectedTabBar( - UUID, + originalRef.UUID, frame, originalRef.name, ); diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index 3a664ea0..eecf004d 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -8,6 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:path/path.dart'; @@ -43,23 +44,29 @@ class PBPrototypeAggregationService { screens.add(node); ///check if any of the [IntermediateNode]s looking for a destination contains their destination. - iterateUnregisterNodes(node, context); + iterateUnregisterNodes(node); } else if (node is PrototypeEnable) { var page = _storage.getPageNodeById( (node as PrototypeEnable).prototypeNode.destinationUUID); if (page == null) { _unregNodes.add(node as PrototypeEnable); } else { - _addDependent(node, page, context); + _addDependent(node, page); } } _unregNodes.removeWhere( (pNode) => pNode.prototypeNode.destinationUUID == node.UUID); } - void _addDependent(PBIntermediateNode target, PBIntermediateNode dependent, - PBContext context) { - context.addDependent(context.tree); + void _addDependent(PBIntermediateNode target, PBIntermediateNode dependent) { + var elementStorage = ElementStorage(); + var targetTree = + elementStorage.treeUUIDs[elementStorage.elementToTree[target.UUID]]; + var dependentTree = + elementStorage.treeUUIDs[elementStorage.elementToTree[dependent.UUID]]; + if (dependentTree != targetTree) { + dependentTree.addDependent(targetTree); + } } /// Provide the `pNode` with the necessary attributes it needs from the `iNode` @@ -106,23 +113,11 @@ class PBPrototypeAggregationService { } } - // TODO: change it on the future - // This temporal solution solves the issue for topological sorting - // when two screens link each other, but one comes first - // and does not get linked to the proper button on the screen - Future linkDanglingPrototypeNodes(PBContext context) async { - if (_unregNodes.isNotEmpty) { - for (var screen in screens) { - iterateUnregisterNodes(screen, context); - } - } - } - - void iterateUnregisterNodes(PBIntermediateNode node, PBContext context) { + void iterateUnregisterNodes(PBIntermediateNode node) { for (var _pNode in _unregNodes) { if (_pNode.prototypeNode.destinationUUID == node.UUID) { _pNode.prototypeNode.destinationName = node.name; - _addDependent(_pNode as PBIntermediateNode, node, context); + _addDependent(_pNode as PBIntermediateNode, node); } } } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 5e5ca683..3e51e41a 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -17,6 +17,7 @@ import 'package:quick_log/quick_log.dart'; /// Usually, we work with its subclasses. We normalize several aspects of data that a sketch node presents in order to work better at the intermediate level. /// Sometimes, PBNode’s do not have a direct representation of a sketch node. For example, most layout nodes are primarily made through and understanding of a need for a layout. import 'package:json_annotation/json_annotation.dart'; +import 'package:uuid/uuid.dart'; part 'pb_intermediate_node.g.dart'; @@ -39,7 +40,8 @@ abstract class PBIntermediateNode //extends Iterable PBGenerator generator; @JsonKey() - final String UUID; + String get UUID => _UUID; + String _UUID; @JsonKey(ignore: true) PBIntermediateConstraints constraints; @@ -79,9 +81,14 @@ abstract class PBIntermediateNode //extends Iterable @JsonKey(ignore: false) String name; - PBIntermediateNode(this.UUID, this.frame, this.name, + PBIntermediateNode(this._UUID, this.frame, this.name, {this.subsemantic, this.constraints}) { logger = Logger(runtimeType.toString()); + if (_UUID == null) { + logger.warning( + 'Generating UUID for $runtimeType-$name as its UUID is null'); + _UUID = Uuid().v4(); + } // _attributes = []; } diff --git a/lib/interpret_and_optimize/helpers/element_storage.dart b/lib/interpret_and_optimize/helpers/element_storage.dart new file mode 100644 index 00000000..74cae9a0 --- /dev/null +++ b/lib/interpret_and_optimize/helpers/element_storage.dart @@ -0,0 +1,18 @@ +import 'dart:collection'; + +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + +class ElementStorage { + static ElementStorage _elementStorageInstance = ElementStorage._internal(); + + /// This [Map] contains the [PBIntermediateNode.UUID] to [PBIntermediateTree.UUID]. + /// + /// This is primarly used to find a particular [PBIntermediateNode]s [PBIntermediateTree] + final elementToTree = {}; + + /// Key value pair for [PBIntermediateTree.UUID] to [PBIntermediateTree] + final treeUUIDs = {}; + + factory ElementStorage() => _elementStorageInstance; + ElementStorage._internal(); +} diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index 09a104f7..65d86b0e 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:quick_log/quick_log.dart'; @@ -95,8 +96,13 @@ class PBSharedInterAggregationService { return; } if (masterNode?.SYMBOL_ID == instanceIntermediateNode?.SYMBOL_ID) { - // instanceIntermediateNode.currentContext - // .addDependent(masterNode.currentContext.tree); + var elementStorage = ElementStorage(); + var masterTree = elementStorage + .treeUUIDs[elementStorage.elementToTree[masterNode.UUID]]; + var tree = elementStorage.treeUUIDs[instanceIntermediateNode.UUID]; + if (masterTree != tree) { + tree.addDependent(masterTree); + } ///Get the attributes of the [masterNode] to the [instanceIntermediateNode] here ([instanceIntermediateNode] attributes) instanceIntermediateNode.functionCallName = masterNode.name; diff --git a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart index 58824b61..7dae31b6 100644 --- a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart @@ -20,7 +20,8 @@ class PBSymbolLinkerService extends AITHandler { // /Linking [PBSharedMasterNode] and [PBSharedInstanceIntermediateNode] together; linking its // /parameter and values. - Future linkSymbols(PBIntermediateTree tree) async { + Future linkSymbols( + PBIntermediateTree tree, PBContext context) async { var rootNode = tree.rootNode; if (rootNode == null) { return Future.value(tree); @@ -42,6 +43,6 @@ class PBSymbolLinkerService extends AITHandler { @override Future handleTree( PBContext context, PBIntermediateTree tree) { - return linkSymbols(tree); + return linkSymbols(tree, context); } } diff --git a/lib/main.dart b/lib/main.dart index 61b38b0a..22ea066c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,7 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; @@ -121,6 +123,13 @@ ${parser.usage} await Future.wait(pbProject.forest.map((tree) { var context = PBContext(processInfo.configuration); + context.project = pbProject; + + /// Assuming that the [tree.rootNode] has the dimensions of the screen. + context.screenFrame = Rectangle.fromPoints( + tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); + context.tree = tree; + tree.context = context; tree.forEach((node) => node.handleChildren(context)); return interpretService .interpretAndOptimize(tree, context, pbProject) diff --git a/test/lib/interpret_and_optimize/intermediate_tree_test.dart b/test/lib/interpret_and_optimize/intermediate_tree_test.dart index c8a77f49..9584448b 100644 --- a/test/lib/interpret_and_optimize/intermediate_tree_test.dart +++ b/test/lib/interpret_and_optimize/intermediate_tree_test.dart @@ -87,7 +87,7 @@ void main() { rootNode = treeBuilder.rootNode; }); - test('Replacement of through [$PBIntermediateNode]', () { + test('Replacement of nodes in [$PBIntermediateNode]', () { var replacementChild3 = MockContainerBuilder.buildContainer( 'REPLACEMENT_C3', parent: null, From 11f984e6acde6dc49574ac323104ed27af2dcc74 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sat, 14 Aug 2021 23:16:40 -0600 Subject: [PATCH 300/404] WIP implementing the directed graph --- lib/eggs/custom_egg.dart | 2 +- lib/eggs/injected_app_bar.dart | 4 +- lib/eggs/injected_tab.dart | 2 +- lib/eggs/injected_tab_bar.dart | 10 +- .../middleware/command_gen_middleware.dart | 2 +- .../utils/middleware_utils.dart | 2 +- .../commands/write_symbol_command.dart | 2 +- .../pb_file_structure_strategy.dart | 4 +- .../pb_generation_configuration.dart | 4 +- ...platform_orientation_generation_mixin.dart | 6 +- .../pb_prototype_aggregation_service.dart | 8 +- .../entities/alignments/flexible.dart | 8 +- .../entities/inherited_bitmap.dart | 4 +- .../entities/inherited_circle.dart | 4 +- .../entities/inherited_container.dart | 12 +- .../entities/inherited_oval.dart | 4 +- .../entities/inherited_polygon.dart | 4 +- .../entities/inherited_scaffold.dart | 10 +- .../entities/inherited_shape_group.dart | 8 +- .../entities/inherited_shape_path.dart | 4 +- .../entities/inherited_star.dart | 4 +- .../entities/inherited_text.dart | 15 +- .../entities/inherited_triangle.dart | 4 +- .../entities/injected_container.dart | 4 +- .../entities/layouts/column.dart | 4 +- .../entities/layouts/row.dart | 6 +- .../rules/container_constraint_rule.dart | 2 +- .../layouts/rules/container_rule.dart | 2 +- .../entities/layouts/rules/handle_flex.dart | 2 +- .../rules/stack_reduction_visual_rule.dart | 2 +- .../entities/layouts/stack.dart | 16 +- .../layouts/temp_group_layout_node.dart | 6 +- .../entities/pb_shared_instance.dart | 4 +- .../entities/pb_shared_master_node.dart | 50 +--- .../entities/pb_shared_master_node.g.dart | 16 +- .../subclasses/pb_intermediate_node.dart | 29 ++- .../abstract_intermediate_node_factory.dart | 14 +- .../helpers/align_strategy.dart | 19 +- .../helpers/child_strategy.dart | 7 +- .../helpers/pb_context.dart | 2 +- .../helpers/pb_intermediate_node_tree.dart | 242 ++++++++++-------- .../helpers/pb_intermediate_node_tree.g.dart | 4 +- .../helpers/pb_project.dart | 2 +- .../pb_layout_generation_service.dart | 44 ++-- ...b_platform_orientation_linker_service.dart | 24 +- pubspec.yaml | 1 + .../interpret_and_optimize/graph_test.dart | 37 +++ .../output_services/project_builder_test.dart | 2 +- 48 files changed, 372 insertions(+), 296 deletions(-) create mode 100644 test/lib/interpret_and_optimize/graph_test.dart diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 942fd370..172a21ca 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -34,7 +34,7 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { var egg = CustomEgg(originalRef.UUID, frame, originalRef.name.replaceAll('', '').pascalCase); - originalRef.children.forEach((child) => egg.addChild(child)); + //FIXME originalRef.children.forEach((child) => egg.addChild(child)); return egg; } } diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 87412348..51ea915c 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -43,7 +43,7 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { return; } - super.addChild(node); + //FIXMEsuper.addChild(node); } @override @@ -81,7 +81,7 @@ class CustomAppBarAlignment extends AlignStrategy { node.middleItem.frame, name: node.middleItem.name, ) - ..addChild(node.middleItem) + //FIXME ..addChild(node.middleItem) ..attributeName = 'title'; var target = diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 6af2f967..985960a6 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -47,7 +47,7 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { ///Clean the node so that it doesn't get interpreted as a plugin again. // designNode.interpretNode(currentContext).then(tab.addChild); - tab.addChild(designNode); + //FIXME tab.addChild(designNode); } return tab; } diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 56839ee7..8331e7dd 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -31,11 +31,11 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override void addChild(node) { if (node is PBInheritedIntermediate) { - if (node.name.contains('')) { - assert(node is! Tab, 'node should be a Tab'); - node.attributeName = 'tab'; - children.add(node); - } + //FIXME // if (node.name.contains('')) { + // assert(node is! Tab, 'node should be a Tab'); + // node.attributeName = 'tab'; + // children.add(node); + // } } if (node is Tab) { diff --git a/lib/generation/generators/middleware/command_gen_middleware.dart b/lib/generation/generators/middleware/command_gen_middleware.dart index 1e64e72c..9159f8a7 100644 --- a/lib/generation/generators/middleware/command_gen_middleware.dart +++ b/lib/generation/generators/middleware/command_gen_middleware.dart @@ -40,7 +40,7 @@ class CommandGenMiddleware extends Middleware command = ExportPlatformCommand( tree.UUID, - context.tree.data.platform, + context.tree.generationViewData.platform, tree.identifier, tree.rootNode.name.snakeCase, generationManager.generate(tree.rootNode, context), diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index afd4c569..d88f044c 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -30,7 +30,7 @@ class MiddlewareUtils { stateBuffer.write(MiddlewareUtils.generateVariable(node)); } node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - context.tree.data = context.managerData; + context.tree.generationViewData = context.managerData; var variationNode = state.variation.node; if (variationNode is PBSharedMasterNode && diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 7606b4f5..fb4282ea 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -22,7 +22,7 @@ class WriteSymbolCommand extends NodeFileStructureCommand { FileOwnership ownership = FileOwnership.PBC}) : super(UUID, code, ownership); - /// Writes a symbol file containing [data] with [fileName] as its filename. + /// Writes a symbol file containing [generationViewData] with [fileName] as its filename. /// /// Returns path to the file that was created. @override diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index a4f30eaa..89b44f94 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -206,10 +206,10 @@ abstract class FileStructureStrategy implements CommandInvoker { fileObservers.forEach((observer) => observer.fileCreated(path, UUID)); } - /// Appends [data] into [directory] with the file [name] + /// Appends [generationViewData] into [directory] with the file [name] /// /// The method is going to be identical to [writeDataToFile], however, - /// it going to try to append [data] to the file in the [directory]. If + /// it going to try to append [generationViewData] to the file in the [directory]. If /// no file is found, then its going to run [writeDataToFile]. [appendIfFound] flag /// appends the information only if that information does not exist in the file. If no /// [ModFile] function is found, its going to append the information at the end of the lines diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 77d49d71..0b510038 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -96,8 +96,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { fileStructureStrategy.addImportsInfo(tree, context); context.generationManager = generationManager; - generationManager.data = tree.data; - tree.data.addImport(FlutterImport('material.dart', 'flutter')); + generationManager.data = tree.generationViewData; + tree.generationViewData.addImport(FlutterImport('material.dart', 'flutter')); // Relative path to the file to create var relPath = p.join(tree.name.snakeCase, tree.identifier); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart index dcf9a2ca..cf5f175d 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart @@ -80,14 +80,14 @@ mixin PBPlatformOrientationGeneration { if (map.length > 1) { var platform = PBPlatformOrientationLinkerService() - .stripPlatform(context.tree.data.platform); + .stripPlatform(context.tree.generationViewData.platform); if (!node.name.contains('_$platform')) { node.name += '_$platform'; } } - if (map[context.tree.data.platform].length > 1) { + if (map[context.tree.generationViewData.platform].length > 1) { var orientation = PBPlatformOrientationLinkerService() - .stripOrientation(context.tree.data.orientation); + .stripOrientation(context.tree.generationViewData.orientation); if (!node.name.contains('_$orientation')) { node.name += '_$orientation'; } diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index eecf004d..5ba9b902 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -80,7 +80,7 @@ class PBPrototypeAggregationService { iNode.frame, (iNode as PBInheritedIntermediate).prototypeNode, ); - destHolder.addChild(iNode); + //FIXME destHolder.addChild(iNode); return destHolder; } else if (iNode is PBLayoutIntermediateNode) { var destHolder = PBDestHolder( @@ -88,7 +88,7 @@ class PBPrototypeAggregationService { iNode.frame, iNode.prototypeNode, ); - destHolder.addChild(iNode); + //FIXME destHolder.addChild(iNode); return destHolder; } else if (iNode is InjectedContainer) { var destHolder = PBDestHolder( @@ -96,7 +96,7 @@ class PBPrototypeAggregationService { iNode.frame, iNode.prototypeNode, ); - destHolder.addChild(iNode); + //FIXME destHolder.addChild(iNode); return destHolder; } else if (iNode is Tab) { var destHolder = PBDestHolder( @@ -105,7 +105,7 @@ class PBPrototypeAggregationService { iNode.prototypeNode, ); iNode.children.forEach((element) { - destHolder.addChild(element); + //FIXME destHolder.addChild(element); }); return destHolder; } else { diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index d02d2826..62f9735d 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -15,7 +15,7 @@ class Flexible extends PBVisualIntermediateNode { Flexible( String UUID, Rectangle frame, { - child, + // child, this.flex, }) : super( UUID, @@ -24,9 +24,9 @@ class Flexible extends PBVisualIntermediateNode { ) { generator = PBFlexibleGenerator(); childrenStrategy = OneChildStrategy('child'); - if(child != null){ - addChild(child); - } + // if(child != null){ + // addChild(child); + // } } @override diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index 9a0ac5b0..0fea39e9 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -12,6 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:pbdl/pbdl.dart'; // import 'dart:math'; import 'package:quick_log/quick_log.dart'; @@ -60,7 +61,8 @@ class InheritedBitmap extends PBVisualIntermediateNode ..originalRef = json; @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => (InheritedBitmap.fromJson(json) as InheritedBitmap)..originalRef = json; } diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 4b50a06d..29d4ec73 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -11,6 +11,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; part 'inherited_circle.g.dart'; @@ -59,6 +60,7 @@ class InheritedCircle extends PBVisualIntermediateNode ..originalRef = json; @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => InheritedCircle.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index e2ebac2a..0100bcae 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -15,6 +15,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; part 'inherited_container.g.dart'; @@ -62,16 +63,15 @@ class InheritedContainer extends PBVisualIntermediateNode } static PBIntermediateNode fromJson(Map json) { - var container = _$InheritedContainerFromJson(json) - ..originalRef = json; - - container.mapRawChildren(json); + var container = _$InheritedContainerFromJson(json)..originalRef = json; container.auxiliaryData.borderInfo.borderRadius = json['fixedRadius']; return container; } @override - PBIntermediateNode createIntermediateNode(Map json) => - InheritedContainer.fromJson(json); + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) { + return InheritedContainer.fromJson(json)..mapRawChildren(json, tree); + } } diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index 273ef014..de0682c7 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -14,6 +14,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:quick_log/quick_log.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; @@ -58,6 +59,7 @@ class InheritedOval extends PBVisualIntermediateNode ..originalRef = json; @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => InheritedOval.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index cae5ba68..314ce0b2 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -17,6 +17,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermedia import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; part 'inherited_polygon.g.dart'; @@ -63,6 +64,7 @@ class InheritedPolygon extends PBVisualIntermediateNode ..originalRef = json; @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => InheritedPolygon.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 186617b4..a15c9116 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -16,6 +16,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; import 'package:pbdl/pbdl.dart'; @@ -120,7 +121,7 @@ class InheritedScaffold extends PBVisualIntermediateNode var groupAtt = TempGroupLayoutNode(null, frame) ..attributeName = 'body' ..parent = this; - children.forEach((att) => groupAtt.addChild(att)); + // children.forEach((att) => groupAtt.addChild(att)); // Keep appbar and tabbar var appBar = getAttributeNamed('appBar'); @@ -140,13 +141,14 @@ class InheritedScaffold extends PBVisualIntermediateNode var artboard = _$InheritedScaffoldFromJson(json)..originalRef = json; //Map artboard children by calling `addChild` method - artboard.mapRawChildren(json); + // artboard.mapRawChildren(json); return artboard; } @override - PBIntermediateNode createIntermediateNode(Map json) => - InheritedScaffold.fromJson(json); + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => + InheritedScaffold.fromJson(json)..mapRawChildren(json, tree); // @override // set child(PBIntermediateNode node) { diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index 5f70f377..63170195 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -16,6 +16,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermedia import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; import 'package:path/path.dart' as p; part 'inherited_shape_group.g.dart'; @@ -58,12 +59,13 @@ class InheritedShapeGroup extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) { var group = _$InheritedShapeGroupFromJson(json)..originalRef = json; - group.mapRawChildren(json); + // group.mapRawChildren(json); return group; } @override - PBIntermediateNode createIntermediateNode(Map json) => - InheritedShapeGroup.fromJson(json); + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => + InheritedShapeGroup.fromJson(json)..mapRawChildren(json, tree); } diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index aa8db429..60686716 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -17,6 +17,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermedia import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; part 'inherited_shape_path.g.dart'; @@ -105,6 +106,7 @@ class InheritedShapePath extends PBVisualIntermediateNode ..originalRef = json; @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => InheritedShapePath.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index c83d6d69..a1edc621 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -16,6 +16,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermedia import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; part 'inherited_star.g.dart'; @@ -64,6 +65,7 @@ class InheritedStar extends PBVisualIntermediateNode ..originalRef = json; @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => InheritedStar.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 02d690f0..d27f63bd 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -1,4 +1,5 @@ import 'dart:math'; +import 'package:directed_graph/directed_graph.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_text_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; @@ -13,6 +14,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermedia import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; part 'inherited_text.g.dart'; @@ -100,17 +102,22 @@ class InheritedText extends PBVisualIntermediateNode PBColor.fromJson(json['style']['textStyle']['fontColor']); @override - PBIntermediateNode createIntermediateNode(Map json) { + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) { var inheritedText = InheritedText.fromJson(json); - // Return an [InheritedContainer] that wraps this text - return InheritedContainer( + var container = InheritedContainer( inheritedText.UUID, inheritedText.frame, // topLeftCorner: inheritedText .frame.topLeft, // bottomRightCorner: inheritedText .frame.bottomRight, name: inheritedText.name, originalRef: json, - )..addChild(inheritedText); + ); + tree.addEdges(Vertex(container), [Vertex(inheritedText)]); + + // Return an [InheritedContainer] that wraps this text + return container; + //..addChild(inheritedText); } } diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 9f3fa8ae..1dbf0133 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -17,6 +17,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermedia import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; part 'inherited_triangle.g.dart'; @@ -60,6 +61,7 @@ class InheritedTriangle extends PBVisualIntermediateNode _$InheritedTriangleFromJson(json)..originalRef = json; @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => InheritedTriangle.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index bdee3543..4d234ae3 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -16,6 +16,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; part 'injected_container.g.dart'; @@ -56,6 +57,7 @@ class InjectedContainer extends PBVisualIntermediateNode _$InjectedContainerFromJson(json); @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => InjectedContainer.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/layouts/column.dart b/lib/interpret_and_optimize/entities/layouts/column.dart index 016c07c1..37d4d64f 100644 --- a/lib/interpret_and_optimize/entities/layouts/column.dart +++ b/lib/interpret_and_optimize/entities/layouts/column.dart @@ -40,7 +40,7 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { PBContext currentContext, String name) { var col = PBIntermediateColumnLayout(null, name: name); col.prototypeNode = prototypeNode; - children.forEach((child) => col.addChild(child)); + //FIXME children.forEach((child) => col.addChild(child)); return col; } } @@ -91,7 +91,7 @@ class ColumnAlignment extends AlignStrategy { top: 0.0, bottom: 0.0, ); - padding.addChild(node.children[i]); + //FIXME padding.addChild(node.children[i]); //Replace Children. node.children[i] = padding; diff --git a/lib/interpret_and_optimize/entities/layouts/row.dart b/lib/interpret_and_optimize/entities/layouts/row.dart index 955bf599..86f48a26 100644 --- a/lib/interpret_and_optimize/entities/layouts/row.dart +++ b/lib/interpret_and_optimize/entities/layouts/row.dart @@ -36,7 +36,7 @@ class PBIntermediateRowLayout extends PBLayoutIntermediateNode { PBContext currentContext, String name) { var row = PBIntermediateRowLayout(name: name); row.prototypeNode = prototypeNode; - children.forEach((child) => row.addChild(child)); + //FIXME children.forEach((child) => row.addChild(child)); return row; } @@ -87,7 +87,7 @@ class RowAlignment extends AlignStrategy { left: 0.0, right: 0.0, ); - padding.addChild(node.children[i]); + //FIXME padding.addChild(node.children[i]); //Replace Children. node.children[i] = padding; @@ -99,7 +99,7 @@ class RowAlignment extends AlignStrategy { PBContext currentContext, String name) { var row = PBIntermediateRowLayout(name: name); // row.prototypeNode = prototypeNode; - children.forEach((child) => row.addChild(child)); + //FIXME children.forEach((child) => row.addChild(child)); return row; } diff --git a/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart index 85d06eb3..b441b459 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/container_constraint_rule.dart @@ -13,7 +13,7 @@ class ContainerConstraintRule extends PostConditionRule { name: currentNode.name, // constraints: currentNode.constraints ); - container.addChild(currentNode); + //FIXME container.addChild(currentNode); return container; } return currentNode; diff --git a/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart index 85e330a4..8b0c802f 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart @@ -54,7 +54,7 @@ class ContainerPostRule extends PostConditionRule { pbvisual = (layout as PBLayoutIntermediateNode) .children .firstWhere((element) => element is PBVisualIntermediateNode); - pbvisual.addChild(pblayout); + //FIXME pbvisual.addChild(pblayout); layout = pbvisual; return layout; } diff --git a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart index 43ddac6f..f70aef6a 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/handle_flex.dart @@ -85,5 +85,5 @@ PBIntermediateNode _putChildInFlex( : _calculateWidth(child.frame.topLeft, child.frame.bottomRight); var flex = _calculateFlex(widgetLength.abs(), parentLength.abs()); - return Flexible(null, child.frame, child: child, flex: flex); + //FIXMEreturn Flexible(null, child.frame, child: child, flex: flex); } diff --git a/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart index 9607aec9..b3011432 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart @@ -28,7 +28,7 @@ class StackReductionVisualRule extends PostConditionRule { (element) => element is PBVisualIntermediateNode && element.children.isEmpty); - wrapper.addChild(child); + //FIXME wrapper.addChild(child); if ((layout as PBIntermediateStackLayout).prototypeNode != null) { if (wrapper is PBInheritedIntermediate) { (wrapper as PBInheritedIntermediate).prototypeNode = diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 3a9bd5f6..87f22559 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -32,17 +32,17 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { @override void resize(PBContext context) { - var depth = context.tree?.depthOf(this); + //FIXMEar depth = context.tree?.depthOf(this); /// Since there are cases where [Stack] are being created, and /// childrend are being populated, and consequently [Stack.resize] is being /// called, then [depth] could be null. [depth] is null when the [PBIntermediateTree] /// has not finished creating and converting PBDL nodes into [PBIntermediateNode]. - if (depth != null && depth <= 1 && depth >= 0) { - frame = context.canvasFrame; - } else { - super.resize(context); - } + //FIXME if (depth != null && depth <= 1 && depth >= 0) { + //FIXME frame = context.canvasFrame; + //FIXME } else { + //FIXME super.resize(context); + //FIXME } } @override @@ -53,8 +53,8 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { children.forEach((element) => frame.boundingBox(element.frame)); var stack = PBIntermediateStackLayout(name: name)..frame = frame; - stack.prototypeNode = prototypeNode; - children.forEach((child) => stack.addChild(child)); + //FIXME stack.prototypeNode = prototypeNode; + //FIXME children.forEach((child) => stack.addChild(child)); return stack; } diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index d151a255..d2bcfc65 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; @@ -60,13 +61,14 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode // . .frame.bottomRight = Point.bottomRightFromJson(json) ..originalRef = json; - tempGroup.mapRawChildren(json); + //FIXME tempGroup.mapRawChildren(json); return tempGroup; } @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => (TempGroupLayoutNode.fromJson(json) as TempGroupLayoutNode) ..originalRef = json; } diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 9a7bf63e..4eb603e6 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_instance_overridable_value.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -93,7 +94,8 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode ..originalRef = json; @override - PBIntermediateNode createIntermediateNode(Map json) => + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => PBSharedInstanceIntermediateNode.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 30db0070..77e2d08a 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -12,6 +12,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermedia import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/override_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/value_objects/pb_symbol_master_params.dart'; import 'package:quick_log/quick_log.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -39,20 +40,6 @@ class PBSharedMasterNode extends PBVisualIntermediateNode List parametersDefinition; Map parametersDefsMap = {}; - ///The children that makes the UI of the [PBSharedMasterNode]. The children are going to be wrapped - ///using a [TempGroupLayoutNode] as the root Node. - // set children(List children) { - // child ??= TempGroupLayoutNode(null, null, - // currentContext: currentContext, name: name); - // if (child is PBLayoutIntermediateNode) { - // children.forEach((element) => child.addChild(element)); - // } else { - // child = TempGroupLayoutNode(null, null, - // currentContext: currentContext, name: name) - // ..replaceChildren([child, ...children]); - // } - // } - ///The properties that could be be overridable on a [PBSharedMasterNode] @JsonKey(name: 'overrideProperties') List overridableProperties; @@ -99,42 +86,17 @@ class PBSharedMasterNode extends PBVisualIntermediateNode childrenStrategy = TempChildrenStrategy('child'); overridableProperties.forEach(OverrideHelper.addProperty); - - // this.currentContext.screenBottomRightCorner = Point( - // originalRef.boundaryRectangle.x + originalRef.boundaryRectangle.width, - // originalRef.boundaryRectangle.y + originalRef.boundaryRectangle.height); - // this.currentContext.screenTopLeftCorner = - // Point(originalRef.boundaryRectangle.x, originalRef.boundaryRectangle.y); - - // parametersDefinition = overridableProperties.map((p) { - // var PBSymMasterP = PBSymbolMasterParameter( - // // p._friendlyName, - // p.type, - // p.value, - // p.UUID, - // p.canOverride, - // p.propertyName, - // /* Removed Parameter Definition as it was accepting JSON?*/ - // null, // TODO: @Eddie - // currentContext.screenTopLeftCorner.x, - // currentContext.screenTopLeftCorner.y, - // currentContext.screenBottomRightCorner.x, - // currentContext.screenBottomRightCorner.y, - // context: currentContext); - // parametersDefsMap[p.propertyName] = PBSymMasterP; - // return PBSymMasterP; - // }).toList() - // ..removeWhere((p) => p == null || p.parameterDefinition == null); } static PBIntermediateNode fromJson(Map json) => _$PBSharedMasterNodeFromJson(json) - ..originalRef = json - ..mapRawChildren(json); + ..originalRef = json; + // ..mapRawChildren(json); @override - PBIntermediateNode createIntermediateNode(Map json) => - PBSharedMasterNode.fromJson(json); + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => + PBSharedMasterNode.fromJson(json)..mapRawChildren(json, tree); } @JsonSerializable() diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart index 0b579a6f..837beb0a 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart @@ -45,14 +45,14 @@ Map _$PBSharedMasterNodeToJson(PBSharedMasterNode instance) => PBSharedParameterProp _$PBSharedParameterPropFromJson( Map json) { - return PBSharedParameterProp( - json['type'] as String, - json['value'] == null - ? null - : PBIntermediateNode.fromJson(json['value'] as Map), - PBSharedParameterProp._propertyNameFromJson(json['name'] as String), - json['UUID'] as String, - ); + //FIXME // PBSharedParameterProp( + // json['type'] as String, + // json['value'] == null + // ? null + // : PBIntermediateNode.fromJson(json['value'] as Map), + // PBSharedParameterProp._propertyNameFromJson(json['name'] as String), + // json['UUID'] as String, + // ); } Map _$PBSharedParameterPropToJson( diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 3e51e41a..0ca80dfc 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -1,6 +1,7 @@ import 'dart:collection'; import 'dart:math'; +import 'package:directed_graph/directed_graph.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; @@ -125,12 +126,15 @@ abstract class PBIntermediateNode //extends Iterable } /// Adds child to node. - void addChild(PBIntermediateNode node) { - childrenStrategy.addChild(this, node); + // void addChild(PBIntermediateNode node) { + // childrenStrategy.addChild(this, node); - /// Checking the constrains of the [node] being added to the tree, smoe of the - /// constrains could be inherited to that section of the sub-tree. - } + // /// Checking the constrains of the [node] being added to the tree, smoe of the + // /// constrains could be inherited to that section of the sub-tree. + // } + + String getAttributeNameOf(PBIntermediateNode node) => + childrenStrategy.attributeName; @override int get hashCode => UUID.hashCode; @@ -154,16 +158,19 @@ abstract class PBIntermediateNode //extends Iterable } } - factory PBIntermediateNode.fromJson(Map json) => - AbstractIntermediateNodeFactory.getIntermediateNode(json); + factory PBIntermediateNode.fromJson(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => + AbstractIntermediateNodeFactory.getIntermediateNode(json, parent, tree); Map toJson() => _$PBIntermediateNodeToJson(this); - void mapRawChildren(Map json) { + void mapRawChildren(Map json, PBIntermediateTree tree) { var rawChildren = json['children'] as List; - rawChildren?.forEach((child) { - if (child != null) { - addChild(PBIntermediateNode.fromJson(child)); + rawChildren?.forEach((rawChild) { + if (rawChild != null) { + PBIntermediateNode.fromJson(rawChild, this, tree); + // tree.addEdges(Vertex(rawChild), [Vertex(parent)]); + // addChild();PBIntermediateNode.fromJson(rawChild) } }); } diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index 022a3542..b975ce7c 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -1,3 +1,4 @@ +import 'package:directed_graph/directed_graph.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_circle.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; @@ -35,24 +36,28 @@ class AbstractIntermediateNodeFactory { PBSharedInstanceIntermediateNode('$PBSharedInstanceIntermediateNode', null), PBSharedMasterNode('$PBSharedMasterNode', null), TempGroupLayoutNode('$TempGroupLayoutNode', null), - PBIntermediateTree(), }; AbstractIntermediateNodeFactory(); - static dynamic getIntermediateNode(Map json) { + static dynamic getIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) { var className = json[INTERMEDIATE_TYPE]; if (className != null) { for (var candidate in _intermediateNodes) { if (candidate.type == className) { - var iNode = candidate.createIntermediateNode(json); + var iNode = candidate.createIntermediateNode(json, parent, tree); // Check if `iNode` is a tag var tag = PBPluginListHelper().returnAllowListNodeIfExists(iNode); // Return tag if it exists if (tag != null) { + tree.addEdges( + parent == null ? null : Vertex(parent), [Vertex(tag)]); return tag; } + tree.addEdges( + parent == null ? null : Vertex(parent), [Vertex(iNode)]); return iNode; } } @@ -84,5 +89,6 @@ class AbstractIntermediateNodeFactory { abstract class IntermediateNodeFactory { String type; - dynamic createIntermediateNode(Map json); + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree); } diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 3ea0cfeb..bcf90d81 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -1,3 +1,4 @@ +import 'package:directed_graph/directed_graph.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; @@ -54,8 +55,11 @@ class PaddingAlignment extends AlignStrategy { top: (child.frame.topLeft.y - node.frame.topLeft.y).abs(), bottom: (child.frame.bottomRight.y - node.frame.bottomRight.y).abs(), ); - padding.addChild(child); - node.addChild(padding); + context.tree.addEdges(Vertex(padding), [Vertex(child)]); + context.tree.addEdges(Vertex(node), [Vertex(padding)]); + + // padding.addChild(child); + // node.addChild(padding); super._setConstraints(context, node); } } @@ -73,6 +77,7 @@ class PositionedAlignment extends AlignStrategy { @override void align(PBContext context, PBIntermediateStackLayout node) { var alignedChildren = []; + var tree = context.tree; node.children.skipWhile((att) { var child = att; @@ -85,7 +90,7 @@ class PositionedAlignment extends AlignStrategy { return false; }).forEach((att) { var child = att; - alignedChildren.add(InjectedPositioned(null, child.frame, + var injectedPositioned = InjectedPositioned(null, child.frame, constraints: child.constraints, valueHolder: PositionedValueHolder( top: child.frame.topLeft.y - node.frame.topLeft.y, @@ -93,10 +98,12 @@ class PositionedAlignment extends AlignStrategy { left: child.frame.topLeft.x - node.frame.topLeft.x, right: node.frame.bottomRight.x - child.frame.bottomRight.x, width: child.frame.width, - height: child.frame.height)) - ..parent = child.parent - ..addChild(child)); + height: child.frame.height)); + alignedChildren.add(injectedPositioned); + tree.addEdges(Vertex(injectedPositioned), [Vertex(child)]); }); + + tree.removeEdges(Vertex(node)); node.replaceChildren(alignedChildren, context); super._setConstraints(context, node); } diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 24edd4c2..ed732fd9 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -70,15 +70,16 @@ class TempChildrenStrategy extends ChildrenStrategy { if (group != null && target.children.length == 1) { // Calculate new frame based on incoming child var newFrame = group.frame.boundingBox(children.frame); - group.addChild(children); + + //FIXMEgroup.addChild(children); group.frame = newFrame; } else if (target.children.isNotEmpty) { var temp = TempGroupLayoutNode(null, null, name: children.name) - ..addChild(children) + //FIXME ..addChild(children) ..parent = target; // Add target's existing children to temp group layout target.children.forEach((child) { - temp.addChild(child); + //FIXME temp.addChild(child); child.parent = temp; }); // Calculate bounding box from all children diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 92cbee24..295e8e7c 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -42,7 +42,7 @@ class PBContext { ///TODO: This is going to change to the [GenerationConfiguration]. PBGenerationManager generationManager; - PBGenerationViewData get managerData => tree?.data; + PBGenerationViewData get managerData => tree?.generationViewData; PBContext(this.configuration, {this.tree, diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 9a76099c..7ec336d3 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -3,14 +3,17 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart'; +import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; import 'package:tuple/tuple.dart'; import 'dart:collection'; import 'package:uuid/uuid.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:directed_graph/directed_graph.dart'; part 'pb_intermediate_node_tree.g.dart'; @@ -21,8 +24,8 @@ enum TREE_TYPE { } @JsonSerializable() -class PBIntermediateTree extends Iterable - implements IntermediateNodeFactory { +class PBIntermediateTree extends DirectedGraph { + Logger _logger; String _UUID; String get UUID => _UUID; @@ -46,17 +49,18 @@ class PBIntermediateTree extends Iterable @JsonKey(ignore: true) bool lockData = false; - PBGenerationViewData _data; + PBGenerationViewData _generationViewData; @JsonKey(ignore: true) - PBGenerationViewData get data => _data; - set data(PBGenerationViewData viewData) { + PBGenerationViewData get generationViewData => _generationViewData; + set generationViewData(PBGenerationViewData viewData) { if (!lockData) { - _data = viewData; + _generationViewData = viewData; } } + @JsonKey(ignore: true) PBIntermediateNode _rootNode; - @JsonKey(name: 'designNode') + @JsonKey(ignore: true) PBIntermediateNode get rootNode => _rootNode; set rootNode(PBIntermediateNode rootNode) { if (!lockData) { @@ -88,6 +92,11 @@ class PBIntermediateTree extends Iterable } } + // JsonKey() + Map> get children => data; + + ElementStorage _elementStorage; + /// [identifier] represents the name of an actual tree or the [DesignScreen], /// while [name] originally represented the [name] of a [DesignPage]. /// @@ -98,10 +107,36 @@ class PBIntermediateTree extends Iterable @JsonKey(name: 'name') String get identifier => _identifier?.snakeCase ?? 'no_name_found'; - PBIntermediateTree({String name, this.context}) { + PBIntermediateTree({ + String name, + this.context, + Map> edges, + Comparator> comparator, + }) : super(edges ?? {}, comparator: comparator) { _name = name; _dependentsOn = {}; _UUID = Uuid().v4(); + _logger = Logger(name ?? runtimeType.toString()); + _elementStorage = ElementStorage(); + } + + @override + void addEdges(Vertex parentVertex, + List> childrenVertices) { + var parent = parentVertex.data; + + childrenVertices.forEach((childVertex) { + var child = childVertex.data; + child.parent = parent; + child.attributeName = parent.getAttributeNameOf(child); + + if (!_elementStorage.elementToTree.containsKey(child.UUID)) { + _elementStorage.elementToTree[child.UUID] = _UUID; + } + }); + + super.addEdges(parentVertex as AITVertex, + childrenVertices.cast()); } /// Adding [PBIntermediateTree] as a dependecy. @@ -117,63 +152,63 @@ class PBIntermediateTree extends Iterable /// /// The entire subtree (starting with [node]) would be eliminated if specified to [eliminateSubTree], /// otherwise, its just going to replace [node] with its [node.children] - bool removeNode(PBIntermediateNode node, {bool eliminateSubTree = false}) { - if (node.parent == null) { - ///TODO: log message - return false; - } - var parent = node.parent; - var removeChild = () => - parent.children.removeWhere((element) => element.UUID == node.UUID); - - if (eliminateSubTree) { - removeChild(); - } else { - /// appending the [PBIntermediateNode]s of the removed [node] - var grandChilds = parent.children - .where((element) => element.UUID == node.UUID) - .map((e) => e.children) - - ///FIXME: Right now the iterator is returning null insize of a list when iterating the tree. - .where((element) => element != null) - .expand((element) => element) - .toList(); - removeChild(); - grandChilds.forEach((element) => parent.addChild(element)); - } - return true; - } + // bool removeNode(PBIntermediateNode node, {bool eliminateSubTree = false}) { + // if (node.parent == null) { + // ///TODO: log message + // return false; + // } + // var parent = node.parent; + // var removeChild = () => + // parent.children.removeWhere((element) => element.UUID == node.UUID); + + // if (eliminateSubTree) { + // removeChild(); + // } else { + // /// appending the [PBIntermediateNode]s of the removed [node] + // var grandChilds = parent.children + // .where((element) => element.UUID == node.UUID) + // .map((e) => e.children) + + // ///FIXME: Right now the iterator is returning null insize of a list when iterating the tree. + // .where((element) => element != null) + // .expand((element) => element) + // .toList(); + // removeChild(); + // grandChilds.forEach((element) => parent.addChild(element)); + // } + // return true; + // } /// Replacing [target] with [replacement] /// /// The entire subtree (starting with [target]) if [replacement] does not [acceptChildren], /// otherwise, those children would be appended to [replacement]. - bool replaceNode(PBIntermediateNode target, PBIntermediateNode replacement, - {bool acceptChildren = false}) { - if (target.parent == null) { - ///TODO: throw correct error/log - throw Error(); - } - - var parent = target.parent; - if (acceptChildren) { - replacement.children.addAll(target.children.map((e) { - e.parent = replacement; - return e; - })); - } - removeNode(target, eliminateSubTree: true); - replacement.attributeName = target.attributeName; - - /// This conditional is for scenarios where both the [target] and the [replacement] are - /// under the same [parent] - if (!parent.children.contains(replacement)) { - parent.children.add(replacement); - replacement.parent = parent; - } - - return true; - } + // bool replaceNode(PBIntermediateNode target, PBIntermediateNode replacement, + // {bool acceptChildren = false}) { + // if (target.parent == null) { + // ///TODO: throw correct error/log + // throw Error(); + // } + + // var parent = target.parent; + // if (acceptChildren) { + // replacement.children.addAll(target.children.map((e) { + // e.parent = replacement; + // return e; + // })); + // } + // removeNode(target, eliminateSubTree: true); + // replacement.attributeName = target.attributeName; + + // /// This conditional is for scenarios where both the [target] and the [replacement] are + // /// under the same [parent] + // if (!parent.children.contains(replacement)) { + // parent.children.add(replacement); + // replacement.parent = parent; + // } + + // return true; + // } /// Checks if the [PBIntermediateTree] is a [TREE_TYPE.SCREEN], /// meaning that the [rootNode] is of type [InheritedScaffold] @@ -183,9 +218,9 @@ class PBIntermediateTree extends Iterable isScreen() && (rootNode as InheritedScaffold).isHomeScreen; /// Finding the depth of the [node] in relation to the [rootNode]. - int depthOf(node) { - return dist(rootNode, node); - } + // int depthOf(node) { + // return dist(rootNode, node); + // } /// Find the distance between [source] and [target], where the [source] is an /// ancestor of [target]. @@ -194,59 +229,37 @@ class PBIntermediateTree extends Iterable /// NOT PRESENT IN THE [PBIntermediateNode], THEN ITS GOING TO RETURN `-1`. /// This is because the nodes of the tree dont have an out going edge /// pointing towards its parents, all directed edges are going down the tree. - int dist(PBIntermediateNode source, PBIntermediateNode target, - {int edgeCost = 1}) { - if (!contains(target)) { - return -1; - } - - var maxPathLength = length + 1; + int dist( + PBIntermediateNode source, + PBIntermediateNode target, + ) => + shortestPath(Vertex(source), Vertex(target))?.length ?? -1; - Queue queue = Queue(); - var dist = { - for (var node in toList()) node: maxPathLength - }; + // @override + // Iterator get iterator => IntermediateDFSIterator(this); - queue.add(source); - dist[source] = 0; + // Iterator get layerIterator => IntermediateLayerIterator(this); - while (queue.isNotEmpty) { - var node = queue.removeFirst(); + Map toJson() => _$PBIntermediateTreeToJson(this); - for (var outNode in node?.children ?? []) { - if (dist[outNode] != maxPathLength) { - continue; - } + static PBIntermediateTree fromJson(Map json) { + var tree = _$PBIntermediateTreeFromJson(json); + var designNode = + PBIntermediateNode.fromJson(json['designNode'], null, tree); + tree.addEdges(Vertex(designNode), []); + tree._rootNode = designNode; - var newDist = dist[node] + edgeCost; - if (newDist < dist[outNode]) { - dist[outNode] = newDist; - queue.add(outNode); - } + List> childrenPointer = json['designNode']['children']; - /// returning the found [target] distance. - if (outNode == target) { - return dist[target]; - } - } - } - return -1; + /// Deserialize the rootNode + /// Then make sure rootNode deserializes the rest of the tree. + // ..addEdges(child, parentList) + // ..tree_type = treeTypeFromJson(json['designNode']); } - @override - Iterator get iterator => IntermediateDFSIterator(this); - - Iterator get layerIterator => IntermediateLayerIterator(this); - - Map toJson() => _$PBIntermediateTreeToJson(this); - - static PBIntermediateTree fromJson(Map json) => - _$PBIntermediateTreeFromJson(json) - ..tree_type = treeTypeFromJson(json['designNode']); - - @override - PBIntermediateTree createIntermediateNode(Map json) => - PBIntermediateTree.fromJson(json); + // @override + // PBIntermediateTree createIntermediateNode(Map json) => + // PBIntermediateTree.fromJson(json); } /// By extending the class, any node could be used in any iterator to traverse its @@ -261,6 +274,19 @@ abstract class TraversableNode { List children; } +class AITVertex extends Vertex { + AITVertex(T data) : super(data); + + @override + int get id => data.UUID.hashCode; + + @override + int get hashCode => data.UUID.hashCode; + + @override + bool operator ==(Object other) => other is AITVertex && other.id == id; +} + TREE_TYPE treeTypeFromJson(Map json) { switch (json['type']) { case 'artboard': diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart index e07b03ed..4a3e298b 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart @@ -9,9 +9,7 @@ part of 'pb_intermediate_node_tree.dart'; PBIntermediateTree _$PBIntermediateTreeFromJson(Map json) { return PBIntermediateTree( name: json['name'] as String, - )..rootNode = json['designNode'] == null - ? null - : PBIntermediateNode.fromJson(json['designNode'] as Map); + ); } Map _$PBIntermediateTreeToJson(PBIntermediateTree instance) => diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index 7bdf4c90..7c08db36 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -86,7 +86,7 @@ class PBProject { var screens = (page['screens'] as Iterable).map((screen) { // Generate Intermedite tree var tree = PBIntermediateTree.fromJson(screen)..name = page['name']; - tree.data = PBGenerationViewData(); + tree.generationViewData = PBGenerationViewData(); if (tree != null) { PBProject.log.fine( diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 3ca6fc59..fa8abc4b 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -94,30 +94,30 @@ class PBLayoutGenerationService extends AITHandler { (node) => node is TempGroupLayoutNode && node.children.length <= 1) .cast() .forEach((tempGroup) { - tree.replaceNode( - tempGroup, - tempGroup.children.isNotEmpty - ? _replaceNode(tempGroup, tempGroup.children.first) - : _replaceNode( - tempGroup, - InjectedContainer( - tempGroup.UUID, tempGroup.frame, - name: tempGroup.name, - // constraints: tempGroup.constraints - ))); + //FIXME // tree.replaceNode( + // tempGroup, + // tempGroup.children.isNotEmpty + // ? _replaceNode(tempGroup, tempGroup.children.first) + // : _replaceNode( + // tempGroup, + // InjectedContainer( + // tempGroup.UUID, tempGroup.frame, + // name: tempGroup.name, + // // constraints: tempGroup.constraints + // ))); }); } /// Transforming the [TempGroupLayoutNode] into regular [PBLayoutIntermediateNode] void _transformGroup(PBIntermediateTree tree) { tree.whereType().forEach((tempGroup) { - tree.replaceNode( - tempGroup, - PBIntermediateStackLayout( - name: tempGroup.name, - constraints: tempGroup.constraints, - )..frame = tempGroup.frame, - acceptChildren: true); + //FIXME // tree.replaceNode( + // tempGroup, + // PBIntermediateStackLayout( + // name: tempGroup.name, + // constraints: tempGroup.constraints, + // )..frame = tempGroup.frame, + // acceptChildren: true); }); } @@ -144,17 +144,17 @@ class PBLayoutGenerationService extends AITHandler { ///If either `currentNode` or `nextNode` is of the same `runtimeType` as the satified [PBLayoutIntermediateNode], ///then its going to use either one instead of creating a new [PBLayoutIntermediateNode]. if (layout.runtimeType == currentNode.runtimeType) { - tree.replaceNode(nextNode, currentNode); + //FIXME tree.replaceNode(nextNode, currentNode); currentNode.addChild(nextNode); } else if (layout.runtimeType == nextNode.runtimeType) { - tree.replaceNode(currentNode, nextNode); + //FIXME tree.replaceNode(currentNode, nextNode); nextNode.addChild(currentNode); } else { ///If neither of the current nodes are of the same `runtimeType` as the layout, we are going to use the actual ///satified [PBLayoutIntermediateNode] to generate the layout. We place both of the nodes inside ///of the generated layout. - tree.removeNode(currentNode, eliminateSubTree: true); - tree.removeNode(nextNode, eliminateSubTree: true); + //FIXME tree.removeNode(currentNode, eliminateSubTree: true); + //FIXME tree.removeNode(nextNode, eliminateSubTree: true); parent.addChild(layout.generateLayout( [currentNode, nextNode], context, diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index ad869626..37b16aca 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -32,14 +32,14 @@ class PBPlatformOrientationLinkerService { /// Populates [tree]'s platform and orientation information /// and adds [tree] to storage. void addOrientationPlatformInformation(PBIntermediateTree tree, PBContext context) { - tree.data.platform = _extractPlatform(tree.name); - tree.data.orientation = _extractOrientation( + tree.generationViewData.platform = _extractPlatform(tree.name); + tree.generationViewData.orientation = _extractOrientation( tree.rootNode .frame.bottomRight, tree.rootNode .frame.topLeft, ); - _platforms.add(tree.data.platform); - _orientations.add(tree.data.orientation); + _platforms.add(tree.generationViewData.platform); + _orientations.add(tree.generationViewData.orientation); // Add orientation builder template to the project // if there are more than 1 orientation on the project @@ -71,8 +71,8 @@ class PBPlatformOrientationLinkerService { var treeName = key.snakeCase; var iterTreeName = currTree.rootNode.name.snakeCase; if (treeName == iterTreeName && - tree.data.orientation == currTree.data.orientation && - tree.data.platform == currTree.data.platform) { + tree.generationViewData.orientation == currTree.generationViewData.orientation && + tree.generationViewData.platform == currTree.generationViewData.platform) { // Rename the tree if both trees have the same orientation and platform tree.rootNode.name = treeName + '_${_mapCounter[iterTreeName]}'; _mapCounter[treeName]++; @@ -117,13 +117,13 @@ class PBPlatformOrientationLinkerService { for (var screen in screens) { // Add orientation to a platform - if (result.containsKey(screen.data.platform)) { - result[screen.data.platform][screen.data.orientation] = screen; + if (result.containsKey(screen.generationViewData.platform)) { + result[screen.generationViewData.platform][screen.generationViewData.orientation] = screen; } // Create entry for current platform-orientation pair else { - result[screen.data.platform] = { - screen.data.orientation: screen, + result[screen.generationViewData.platform] = { + screen.generationViewData.orientation: screen, }; } } @@ -172,8 +172,8 @@ class PBPlatformOrientationLinkerService { List list) { var result = >{}; list.forEach((value) { - var platform = stripPlatform(value.data.platform); - var orientation = stripOrientation(value.data.orientation); + var platform = stripPlatform(value.generationViewData.platform); + var orientation = stripOrientation(value.generationViewData.orientation); if (result.containsKey(platform)) { result[platform].add(orientation); } else { diff --git a/pubspec.yaml b/pubspec.yaml index 9e8a18d2..750573df 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,6 +24,7 @@ dependencies: file: ^6.1.2 pbdl: path: ./pbdl + directed_graph: ^0.2.3 dev_dependencies: pedantic: ^1.8.0 diff --git a/test/lib/interpret_and_optimize/graph_test.dart b/test/lib/interpret_and_optimize/graph_test.dart new file mode 100644 index 00000000..0b52dacd --- /dev/null +++ b/test/lib/interpret_and_optimize/graph_test.dart @@ -0,0 +1,37 @@ +import 'package:directed_graph/directed_graph.dart'; +import 'package:mockito/mockito.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_circle.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:test/test.dart'; + +// import '../output_services/project_builder_test.dart'; + +class MockContainer extends Mock implements InjectedContainer {} + +class MockScaffold extends Mock implements InheritedScaffold {} + +void main() { + group('Testing IntermediateTree', () { + PBIntermediateTree tree; + setUp(() { + tree = PBIntermediateTree( + comparator: (v0, v1) => v0.data.UUID.compareTo(v1.data.UUID)); + }); + + test('', () { + var parent = InheritedContainer('PARENT', null); + var child = InheritedCircle('CHILD', null); + + // var vParent =; + // var vChild = ; + + tree.addEdges(AITVertex(parent), [AITVertex(child)]); + print(tree); + var edges = tree.edges(AITVertex(parent)); + print(tree); + }); + }); +} diff --git a/test/lib/output_services/project_builder_test.dart b/test/lib/output_services/project_builder_test.dart index 4c1b7db5..a46d4b6f 100644 --- a/test/lib/output_services/project_builder_test.dart +++ b/test/lib/output_services/project_builder_test.dart @@ -75,7 +75,7 @@ void main() { when(intermediateTree.rootNode).thenReturn(scaffold); when(intermediateTree.name).thenReturn('testTree'); - when(intermediateTree.data).thenReturn(PBGenerationViewData()); + when(intermediateTree.generationViewData).thenReturn(PBGenerationViewData()); when(intermediateTree.dependentsOn) .thenReturn([].iterator); From 749ed4eb0f278c294c58f7f013ac4a0cb9d42629 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sun, 15 Aug 2021 00:53:41 -0500 Subject: [PATCH 301/404] Implement adding edges for PBEggs instead of adding children directly. --- lib/eggs/custom_egg.dart | 6 ++++- lib/eggs/injected_app_bar.dart | 15 ++++++++----- lib/eggs/injected_back_arrow.dart | 5 ++++- lib/eggs/injected_tab.dart | 7 +++++- lib/eggs/injected_tab_bar.dart | 22 ++++++++++--------- .../generators/plugins/pb_plugin_node.dart | 5 ++++- .../abstract_intermediate_node_factory.dart | 5 ++++- .../helpers/pb_plugin_list_helper.dart | 6 +++-- .../interpret_and_optimize/graph_test.dart | 7 ++++-- 9 files changed, 53 insertions(+), 25 deletions(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 172a21ca..55bc8bec 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:uuid/uuid.dart'; import 'package:recase/recase.dart'; @@ -31,9 +32,12 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { } @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBIntermediateTree tree) { var egg = CustomEgg(originalRef.UUID, frame, originalRef.name.replaceAll('', '').pascalCase); + tree.addEdges(AITVertex(this), + originalRef.children.map((e) => AITVertex(e)).toList()); //FIXME originalRef.children.forEach((child) => egg.addChild(child)); return egg; } diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 51ea915c..7445bc51 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -8,6 +8,8 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; @@ -25,8 +27,7 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { alignStrategy = CustomAppBarAlignment(); } - @override - void addChild(PBIntermediateNode node) { + void addChild(PBIntermediateNode node, PBIntermediateTree tree) { if (node is PBInheritedIntermediate) { var attName = 'child'; if (node.name.contains('')) { @@ -39,7 +40,9 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { attName = 'title'; } node.attributeName = attName; - children.add(node); + + tree.addEdges(AITVertex(this), [AITVertex(node)]); + // children.add(node); return; } @@ -47,14 +50,14 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { } @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBIntermediateTree tree) { var appbar = InjectedAppbar( originalRef.UUID, frame, originalRef.name, ); - - originalRef.children.forEach(addChild); + originalRef.children.forEach((child) => addChild(child, tree)); return appbar; } diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index 8bfff37f..806d144d 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -7,6 +7,8 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; @@ -29,7 +31,8 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { void extractInformation(PBIntermediateNode incomingNode) {} @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBIntermediateTree tree) { return InjectedBackArrow( UUID, frame, diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 985960a6..74a48c9e 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -12,6 +12,8 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { @override PrototypeNode prototypeNode; @@ -34,7 +36,8 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { String semanticName; @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode, + PBIntermediateTree tree) { if (originalNode is PBInheritedIntermediate) { var tab = Tab( originalNode.UUID, @@ -45,6 +48,8 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { if (originalNode is! TempGroupLayoutNode) { var designNode = _convertWrapper(originalNode); + tree.addEdges(AITVertex(this), [AITVertex(designNode)]); + ///Clean the node so that it doesn't get interpreted as a plugin again. // designNode.interpretNode(currentContext).then(tab.addChild); //FIXME tab.addChild(designNode); diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 8331e7dd..a5b8f989 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'dart:math'; import 'injected_tab.dart'; @@ -28,19 +29,19 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { generator = PBTabBarGenerator(); } - @override - void addChild(node) { + void addChild(PBIntermediateNode node, PBIntermediateTree tree) { + //TODO: Solve if statements; node should always be one of the two types if (node is PBInheritedIntermediate) { - //FIXME // if (node.name.contains('')) { - // assert(node is! Tab, 'node should be a Tab'); - // node.attributeName = 'tab'; - // children.add(node); - // } + if (node.name.contains('')) { + assert(node is! Tab, 'node should be a Tab'); + node.attributeName = 'tab'; + tree.addEdges(AITVertex(this), [AITVertex(node)]); + } } if (node is Tab) { node.attributeName = 'tab'; - children.add(node); + tree.addEdges(AITVertex(this), [AITVertex(node)]); } } @@ -48,14 +49,15 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { List layoutInstruction(List layer) {} @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBIntermediateTree tree) { var tabbar = InjectedTabBar( originalRef.UUID, frame, originalRef.name, ); - originalRef.children.forEach(addChild); + originalRef.children.forEach((child) => addChild(child, tree)); return tabbar; } diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index 6d16ea7c..682bffd6 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -3,6 +3,8 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + abstract class PBEgg extends PBVisualIntermediateNode { /// The allow list semantic name to detect this node. String semanticName; @@ -22,7 +24,8 @@ abstract class PBEgg extends PBVisualIntermediateNode { List layoutInstruction(List layer) => layer; - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode); + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode, + PBIntermediateTree tree); void extractInformation(PBIntermediateNode incomingNode); } diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index b975ce7c..bd569bab 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -49,7 +49,10 @@ class AbstractIntermediateNodeFactory { var iNode = candidate.createIntermediateNode(json, parent, tree); // Check if `iNode` is a tag - var tag = PBPluginListHelper().returnAllowListNodeIfExists(iNode); + //? If `iNode` is a tag, do we have to remove any links that \ + //? may have been made during `createIntermediateNode()` ? + var tag = + PBPluginListHelper().returnAllowListNodeIfExists(iNode, tree); // Return tag if it exists if (tag != null) { tree.addEdges( diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index 8bef57cd..7d359a62 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'dart:math'; import 'package:uuid/uuid.dart'; @@ -84,11 +85,12 @@ class PBPluginListHelper { /// Iterates through Plugin List and checks for a match of `node.name`. /// Returns the PluginNode associated if it exists. - PBEgg returnAllowListNodeIfExists(PBIntermediateNode node) { + PBEgg returnAllowListNodeIfExists( + PBIntermediateNode node, PBIntermediateTree tree) { if (node != null) { for (var key in allowListNames.keys) { if (node.name?.contains(key) ?? false) { - return allowListNames[key].generatePluginNode(node.frame, node); + return allowListNames[key].generatePluginNode(node.frame, node, tree); } } } diff --git a/test/lib/interpret_and_optimize/graph_test.dart b/test/lib/interpret_and_optimize/graph_test.dart index 0b52dacd..96fce836 100644 --- a/test/lib/interpret_and_optimize/graph_test.dart +++ b/test/lib/interpret_and_optimize/graph_test.dart @@ -24,13 +24,16 @@ void main() { test('', () { var parent = InheritedContainer('PARENT', null); var child = InheritedCircle('CHILD', null); + var child2 = InheritedCircle('child2', null); + var child3 = InheritedCircle('CHILD3', null); // var vParent =; // var vChild = ; - tree.addEdges(AITVertex(parent), [AITVertex(child)]); - print(tree); + tree.addEdges(AITVertex(parent), + [AITVertex(child), AITVertex(child2), AITVertex(child3)]); var edges = tree.edges(AITVertex(parent)); + tree.removeEdges(AITVertex(parent)); print(tree); }); }); From ac591648207f5a683d29ba8972a155af6ec8bc4f Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sun, 15 Aug 2021 00:53:41 -0500 Subject: [PATCH 302/404] Implement adding edges for PBEggs instead of adding children directly. --- lib/eggs/custom_egg.dart | 6 ++- lib/eggs/injected_app_bar.dart | 29 +++++++------ lib/eggs/injected_back_arrow.dart | 5 ++- lib/eggs/injected_tab.dart | 7 ++- lib/eggs/injected_tab_bar.dart | 43 ++++++++++++++----- .../generators/plugins/pb_plugin_node.dart | 5 ++- .../abstract_intermediate_node_factory.dart | 5 ++- .../helpers/pb_plugin_list_helper.dart | 6 ++- .../interpret_and_optimize/graph_test.dart | 7 ++- 9 files changed, 80 insertions(+), 33 deletions(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 172a21ca..55bc8bec 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:uuid/uuid.dart'; import 'package:recase/recase.dart'; @@ -31,9 +32,12 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { } @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBIntermediateTree tree) { var egg = CustomEgg(originalRef.UUID, frame, originalRef.name.replaceAll('', '').pascalCase); + tree.addEdges(AITVertex(this), + originalRef.children.map((e) => AITVertex(e)).toList()); //FIXME originalRef.children.forEach((child) => egg.addChild(child)); return egg; } diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 51ea915c..aa7b2257 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -8,6 +8,8 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; @@ -25,37 +27,38 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { alignStrategy = CustomAppBarAlignment(); } + void addChild(PBIntermediateNode node, PBIntermediateTree tree) {} + + //FIXMEsuper.addChild(node); + @override - void addChild(PBIntermediateNode node) { + String getAttributeNameOf(PBIntermediateNode node) { if (node is PBInheritedIntermediate) { - var attName = 'child'; + // var attName = 'child'; if (node.name.contains('')) { - attName = 'leading'; + return 'leading'; } if (node.name.contains('')) { - attName = 'actions'; + return 'actions'; } if (node.name.contains('')) { - attName = 'title'; + return 'title'; } - node.attributeName = attName; - children.add(node); - return; } - //FIXMEsuper.addChild(node); + return super.getAttributeNameOf(node); } @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBIntermediateTree tree) { var appbar = InjectedAppbar( originalRef.UUID, frame, originalRef.name, ); - - originalRef.children.forEach(addChild); - + tree.addEdges(AITVertex(appbar), + originalRef.children.map((child) => AITVertex(child)).toList()); return appbar; } diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index 8bfff37f..806d144d 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -7,6 +7,8 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; @@ -29,7 +31,8 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { void extractInformation(PBIntermediateNode incomingNode) {} @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBIntermediateTree tree) { return InjectedBackArrow( UUID, frame, diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 985960a6..74a48c9e 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -12,6 +12,8 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { @override PrototypeNode prototypeNode; @@ -34,7 +36,8 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { String semanticName; @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode, + PBIntermediateTree tree) { if (originalNode is PBInheritedIntermediate) { var tab = Tab( originalNode.UUID, @@ -45,6 +48,8 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { if (originalNode is! TempGroupLayoutNode) { var designNode = _convertWrapper(originalNode); + tree.addEdges(AITVertex(this), [AITVertex(designNode)]); + ///Clean the node so that it doesn't get interpreted as a plugin again. // designNode.interpretNode(currentContext).then(tab.addChild); //FIXME tab.addChild(designNode); diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 8331e7dd..05a2affb 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -7,6 +7,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inje import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'dart:math'; import 'injected_tab.dart'; @@ -28,34 +29,54 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { generator = PBTabBarGenerator(); } - @override - void addChild(node) { + void addChild(PBIntermediateNode node, PBIntermediateTree tree) { + //TODO: Solve if statements; node should always be one of the two types if (node is PBInheritedIntermediate) { - //FIXME // if (node.name.contains('')) { - // assert(node is! Tab, 'node should be a Tab'); - // node.attributeName = 'tab'; - // children.add(node); - // } + if (node.name.contains('')) { + assert(node is! Tab, 'node should be a Tab'); + node.attributeName = 'tab'; + tree.addEdges(AITVertex(this), [AITVertex(node)]); + } } if (node is Tab) { node.attributeName = 'tab'; - children.add(node); + tree.addEdges(AITVertex(this), [AITVertex(node)]); + } + } + + @override + String getAttributeNameOf(PBIntermediateNode node) { + if (node is PBInheritedIntermediate) { + if (node.name.contains('')) { + assert(node is! Tab, 'node should be a Tab'); + return 'tab'; + // node.attributeName = 'tab'; + // tree.addEdges(AITVertex(this), [AITVertex(node)]); + } + } + + if (node is Tab) { + return 'tab'; + // node.attributeName = 'tab'; + // tree.addEdges(AITVertex(this), [AITVertex(node)]); } + return super.getAttributeNameOf(node); } @override List layoutInstruction(List layer) {} @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef) { + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBIntermediateTree tree) { var tabbar = InjectedTabBar( originalRef.UUID, frame, originalRef.name, ); - - originalRef.children.forEach(addChild); + tree.addEdges(AITVertex(tabbar), + originalRef.children.map((child) => AITVertex(child)).toList()); return tabbar; } diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index 6d16ea7c..682bffd6 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -3,6 +3,8 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visu import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + abstract class PBEgg extends PBVisualIntermediateNode { /// The allow list semantic name to detect this node. String semanticName; @@ -22,7 +24,8 @@ abstract class PBEgg extends PBVisualIntermediateNode { List layoutInstruction(List layer) => layer; - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode); + PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode, + PBIntermediateTree tree); void extractInformation(PBIntermediateNode incomingNode); } diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index b975ce7c..bd569bab 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -49,7 +49,10 @@ class AbstractIntermediateNodeFactory { var iNode = candidate.createIntermediateNode(json, parent, tree); // Check if `iNode` is a tag - var tag = PBPluginListHelper().returnAllowListNodeIfExists(iNode); + //? If `iNode` is a tag, do we have to remove any links that \ + //? may have been made during `createIntermediateNode()` ? + var tag = + PBPluginListHelper().returnAllowListNodeIfExists(iNode, tree); // Return tag if it exists if (tag != null) { tree.addEdges( diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index 8bef57cd..7d359a62 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'dart:math'; import 'package:uuid/uuid.dart'; @@ -84,11 +85,12 @@ class PBPluginListHelper { /// Iterates through Plugin List and checks for a match of `node.name`. /// Returns the PluginNode associated if it exists. - PBEgg returnAllowListNodeIfExists(PBIntermediateNode node) { + PBEgg returnAllowListNodeIfExists( + PBIntermediateNode node, PBIntermediateTree tree) { if (node != null) { for (var key in allowListNames.keys) { if (node.name?.contains(key) ?? false) { - return allowListNames[key].generatePluginNode(node.frame, node); + return allowListNames[key].generatePluginNode(node.frame, node, tree); } } } diff --git a/test/lib/interpret_and_optimize/graph_test.dart b/test/lib/interpret_and_optimize/graph_test.dart index 0b52dacd..96fce836 100644 --- a/test/lib/interpret_and_optimize/graph_test.dart +++ b/test/lib/interpret_and_optimize/graph_test.dart @@ -24,13 +24,16 @@ void main() { test('', () { var parent = InheritedContainer('PARENT', null); var child = InheritedCircle('CHILD', null); + var child2 = InheritedCircle('child2', null); + var child3 = InheritedCircle('CHILD3', null); // var vParent =; // var vChild = ; - tree.addEdges(AITVertex(parent), [AITVertex(child)]); - print(tree); + tree.addEdges(AITVertex(parent), + [AITVertex(child), AITVertex(child2), AITVertex(child3)]); var edges = tree.edges(AITVertex(parent)); + tree.removeEdges(AITVertex(parent)); print(tree); }); }); From 06d468232be1c4b5a166676b6701765f09277aa3 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 15 Aug 2021 19:58:58 -0600 Subject: [PATCH 303/404] WIP desearializing the json using the tree converter --- .../pb_prototype_linker_service.dart | 12 +- .../entities/inherited_scaffold.dart | 2 + .../subclasses/pb_intermediate_node.dart | 7 - .../abstract_intermediate_node_factory.dart | 18 ++- .../helpers/align_strategy.dart | 2 +- .../helpers/child_strategy.dart | 67 +++++----- .../helpers/pb_intermediate_node_tree.dart | 125 ++++++------------ 7 files changed, 88 insertions(+), 145 deletions(-) diff --git a/lib/generation/prototyping/pb_prototype_linker_service.dart b/lib/generation/prototyping/pb_prototype_linker_service.dart index bdcd5e2e..290e0d55 100644 --- a/lib/generation/prototyping/pb_prototype_linker_service.dart +++ b/lib/generation/prototyping/pb_prototype_linker_service.dart @@ -40,12 +40,10 @@ class PBPrototypeLinkerService { void addAndPopulatePrototypeNode( var currentNode, var rootNode, PBContext context) async { await _prototypeStorage.addPrototypeInstance(currentNode, context); - currentNode = - _aggregationService.populatePrototypeNode(context, currentNode) ?? currentNode; - - context.tree.replaceNode(, replacement); - - // PBIntermediateNodeSearcherService.replaceNodeInTree( - // rootNode, currentNode, currentNode.UUID); + var pNode = + _aggregationService.populatePrototypeNode(context, currentNode); + if(pNode != null){ + context.tree.replaceNode(currentNode, pNode); + } } } diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 22078f08..4cc6f773 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -6,6 +6,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -42,6 +43,7 @@ class InheritedScaffold extends PBVisualIntermediateNode {this.isHomeScreen, this.prototypeNode}) : super(UUID, frame, name) { generator = PBScaffoldGenerator(); + childrenStrategy = MultipleChildStrategy('body'); } @override diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index d2af5e95..7b30a60b 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -48,13 +48,6 @@ abstract class PBIntermediateNode //extends Iterable @JsonKey(ignore: true) PBIntermediateNode parent; - // @override - // @JsonKey(ignore: true) - // List children = []; - - // @JsonKey(ignore: true) - // PBIntermediateNode get child => children.isEmpty ? null : children.first; - @JsonKey(ignore: true) ChildrenStrategy childrenStrategy = OneChildStrategy('child'); diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index bd569bab..4aa14cf6 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -51,16 +51,20 @@ class AbstractIntermediateNodeFactory { // Check if `iNode` is a tag //? If `iNode` is a tag, do we have to remove any links that \ //? may have been made during `createIntermediateNode()` ? - var tag = + var egg = PBPluginListHelper().returnAllowListNodeIfExists(iNode, tree); // Return tag if it exists - if (tag != null) { - tree.addEdges( - parent == null ? null : Vertex(parent), [Vertex(tag)]); - return tag; + if (egg != null) { + if (parent != null) { + tree.addEdges(Vertex(parent), [Vertex(egg)]); + } + + return egg; + } + if (parent != null) { + tree.addEdges(Vertex(parent), [Vertex(iNode)]); } - tree.addEdges( - parent == null ? null : Vertex(parent), [Vertex(iNode)]); + return iNode; } } diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index b8e23c84..d85c32dc 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -101,7 +101,7 @@ class PositionedAlignment extends AlignStrategy { alignedChildren.add(injectedPositioned); tree.addEdges(Vertex(injectedPositioned), [Vertex(child)]); }); - tree.replaceChildrenOf(node, [alignedChildren]); + tree.replaceChildrenOf(node, alignedChildren); super._setConstraints(context, node); } } diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index ed732fd9..3d759dbe 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:quick_log/quick_log.dart'; abstract class ChildrenStrategy { @@ -9,7 +10,8 @@ abstract class ChildrenStrategy { ChildrenStrategy(this.attributeName, this.overwridable) { logger = Logger(runtimeType.toString()); } - void addChild(PBIntermediateNode target, dynamic children); + void addChild(PBIntermediateNode target, dynamic children, + ChildrenMod addChild, PBIntermediateTree tree); } class OneChildStrategy extends ChildrenStrategy { @@ -17,10 +19,10 @@ class OneChildStrategy extends ChildrenStrategy { : super(attributeName, overridable); @override - void addChild(PBIntermediateNode target, dynamic child) { + void addChild( + PBIntermediateNode target, dynamic child, ChildrenMod addChild, tree) { if (child is PBIntermediateNode) { - child.parent = target; - target.children = [child]; + addChild(target, [child]); } else { logger.warning( 'Tried adding ${child.runtimeType.toString()} to ${target.runtimeType.toString()}'); @@ -33,15 +35,12 @@ class MultipleChildStrategy extends ChildrenStrategy { : super(attributeName, overridable); @override - void addChild(PBIntermediateNode target, children) { + void addChild( + PBIntermediateNode target, children, ChildrenMod addChild, tree) { if (children is List) { - target.children.addAll(children.map((child) { - child.parent = target; - return child; - })); + addChild(target, children); } else if (children is PBIntermediateNode) { - children.parent = target; - target.children.add(children); + addChild(target, [children]); } } } @@ -50,11 +49,10 @@ class NoChildStrategy extends ChildrenStrategy { NoChildStrategy([bool overridable]) : super('N/A', overridable); @override - void addChild(PBIntermediateNode target, children) { - if (children != null) { - logger.warning( - 'Tried adding ${children.runtimeType.toString()} to ${target.runtimeType.toString()}'); - } + void addChild( + PBIntermediateNode target, children, ChildrenMod addChild, tree) { + logger.warning( + 'Tried adding ${children.runtimeType.toString()} to ${target.runtimeType.toString()}'); } } @@ -63,36 +61,33 @@ class TempChildrenStrategy extends ChildrenStrategy { : super(attributeName, overwridable); @override - void addChild(PBIntermediateNode target, children) { - var group = target.children.firstWhere( + void addChild( + PBIntermediateNode target, children, ChildrenMod addChild, tree) { + var targetChildren = tree.childrenOf(target); + var group = targetChildren.firstWhere( (element) => element is TempGroupLayoutNode, orElse: () => null); - if (group != null && target.children.length == 1) { + if (group != null && targetChildren.length == 1) { // Calculate new frame based on incoming child var newFrame = group.frame.boundingBox(children.frame); - - //FIXMEgroup.addChild(children); + addChild(group, targetChildren); group.frame = newFrame; - } else if (target.children.isNotEmpty) { - var temp = TempGroupLayoutNode(null, null, name: children.name) - //FIXME ..addChild(children) - ..parent = target; - // Add target's existing children to temp group layout - target.children.forEach((child) { - //FIXME temp.addChild(child); - child.parent = temp; - }); + } else if (targetChildren.isNotEmpty) { + var temp = TempGroupLayoutNode(null, null, name: children.name); + addChild(temp, targetChildren); + + var tempChildren = tree.childrenOf(temp); + // Calculate bounding box from all children - var frame = temp.children.first.frame; - for (var i = 1; i < temp.children.length; i++) { - frame = frame.boundingBox(temp.children[i].frame); + var frame = tempChildren.first.frame; + for (var i = 1; i < tempChildren.length; i++) { + frame = frame.boundingBox(tempChildren[i].frame); } temp.frame = frame; - target.children = [temp]; + addChild(target, [temp]); } else if (children is PBIntermediateNode) { - children.parent = target; - target.children.add(children); + addChild(target, [children]); } } } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 5795979c..3de0a6ed 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -35,10 +35,6 @@ class PBIntermediateTree extends DirectedGraph { @JsonKey(ignore: true) TREE_TYPE tree_type = TREE_TYPE.SCREEN; - @override - @JsonKey(ignore: true) - String type = 'tree'; - /// This flag makes the data in the [PBIntermediateTree] unmodifiable. Therefore, /// if a change is made and [lockData] is `true`, the change is going to be ignored. /// @@ -92,10 +88,7 @@ class PBIntermediateTree extends DirectedGraph { } } - final _childrenModObservers = >{}; - - // JsonKey() - // Map> get children => data; + final _childrenModObservers = >{}; ElementStorage _elementStorage; @@ -122,35 +115,47 @@ class PBIntermediateTree extends DirectedGraph { _elementStorage = ElementStorage(); } - void addChildrenObeserver(String UUID, ChildrenModification oberver) { + /// These are observers of [Vertex] that will be added into [this] + void addChildrenObeserver(String UUID, ChildrenModEventHandler oberver) { var mods = _childrenModObservers[UUID] ?? []; mods.add(oberver); _childrenModObservers[UUID] = mods; } List childrenOf(PBIntermediateNode node) => - edges(AITVertex(node)).map((e) => e.data); + edges(AITVertex(node)).map((e) => e.data).toList(); @override void addEdges(Vertex parentVertex, - List> childrenVertices) { + [List> childrenVertices]) { var parent = parentVertex.data; - - childrenVertices.forEach((childVertex) { - var child = childVertex.data; - child.parent = parent; - child.attributeName = parent.getAttributeNameOf(child); - - if (!_elementStorage.elementToTree.containsKey(child.UUID)) { - _elementStorage.elementToTree[child.UUID] = _UUID; + if (childrenVertices == null) {} + var children = childrenVertices.map((e) => e.data).toList(); + + /// Passing the responsability of acctually adding the [PBIntermediateNode] into + /// the [tree] to the [parent.childStrategy]. The main reason for this is to enforce + /// the strict policy that some [PBIntermediateNode] have when adding a node. Some + /// nodes might just be allowed to have a single child, while others are can have more that + /// one child. + // ignore: omit_local_variable_types + ChildrenMod addChildren = + (PBIntermediateNode parent, List children) { + children.forEach((child) { + child.parent = parent; + child.attributeName = parent.getAttributeNameOf(child); + + if (!_elementStorage.elementToTree.containsKey(child.UUID)) { + _elementStorage.elementToTree[child.UUID] = _UUID; + } + }); + if (_childrenModObservers.containsKey(parentVertex.data.UUID)) { + _childrenModObservers[UUID].forEach((listener) => listener( + CHILDREN_MOD.CREATED, childrenVertices.map((e) => e.data))); } - }); - if (_childrenModObservers.containsKey(parentVertex.data.UUID)) { - _childrenModObservers[UUID].forEach((listener) => - listener(CHILDREN_MOD.CREATED, childrenVertices.map((e) => e.data))); - } - super.addEdges( - parentVertex as AITVertex, childrenVertices.cast()); + return super.addEdges( + AITVertex(parent), childrenVertices); + }; + parent.childrenStrategy.addChild(parent, children, addChildren, this); } @override @@ -173,37 +178,6 @@ class PBIntermediateTree extends DirectedGraph { } } - /// Removing the [node] from the [PBIntermediateTree] - /// - /// The entire subtree (starting with [node]) would be eliminated if specified to [eliminateSubTree], - /// otherwise, its just going to replace [node] with its [node.children] - // bool removeNode(PBIntermediateNode node, {bool eliminateSubTree = false}) { - // if (node.parent == null) { - // ///TODO: log message - // return false; - // } - // var parent = node.parent; - // var removeChild = () => - // parent.children.removeWhere((element) => element.UUID == node.UUID); - - // if (eliminateSubTree) { - // removeChild(); - // } else { - // /// appending the [PBIntermediateNode]s of the removed [node] - // var grandChilds = parent.children - // .where((element) => element.UUID == node.UUID) - // .map((e) => e.children) - - // ///FIXME: Right now the iterator is returning null insize of a list when iterating the tree. - // .where((element) => element != null) - // .expand((element) => element) - // .toList(); - // removeChild(); - // grandChilds.forEach((element) => parent.addChild(element)); - // } - // return true; - // } - void replaceChildrenOf( PBIntermediateNode parent, List children) { var parentVertex = AITVertex(parent); @@ -220,26 +194,10 @@ class PBIntermediateTree extends DirectedGraph { if (target.parent == null) { throw Error(); } - - // var parent = target.parent; if (acceptChildren) { addEdges(AITVertex(replacement), edges(AITVertex(target))); - // replacement.children.addAll(target.children.map((e) { - // e.parent = replacement; - // return e; - // })); } remove(AITVertex(target)); - // removeNode(target, eliminateSubTree: true); - // replacement.attributeName = target.attributeName; - - /// This conditional is for scenarios where both the [target] and the [replacement] are - /// under the same [parent] - // if (!parent.children.contains(replacement)) { - // parent.children.add(replacement); - // replacement.parent = parent; - // } - return true; } @@ -251,9 +209,9 @@ class PBIntermediateTree extends DirectedGraph { isScreen() && (rootNode as InheritedScaffold).isHomeScreen; /// Finding the depth of the [node] in relation to the [rootNode]. - // int depthOf(node) { - // return dist(rootNode, node); - // } + int depthOf(node) { + return dist(rootNode, node); + } /// Find the distance between [source] and [target], where the [source] is an /// ancestor of [target]. @@ -268,11 +226,6 @@ class PBIntermediateTree extends DirectedGraph { ) => shortestPath(Vertex(source), Vertex(target))?.length ?? -1; - // @override - // Iterator get iterator => IntermediateDFSIterator(this); - - // Iterator get layerIterator => IntermediateLayerIterator(this); - Map toJson() => _$PBIntermediateTreeToJson(this); static PBIntermediateTree fromJson(Map json) { @@ -281,18 +234,15 @@ class PBIntermediateTree extends DirectedGraph { PBIntermediateNode.fromJson(json['designNode'], null, tree); tree.addEdges(Vertex(designNode), []); tree._rootNode = designNode; + return tree; - List> childrenPointer = json['designNode']['children']; + // List> childrenPointer = json['designNode']['children']; /// Deserialize the rootNode /// Then make sure rootNode deserializes the rest of the tree. // ..addEdges(child, parentList) // ..tree_type = treeTypeFromJson(json['designNode']); } - - // @override - // PBIntermediateTree createIntermediateNode(Map json) => - // PBIntermediateTree.fromJson(json); } /// By extending the class, any node could be used in any iterator to traverse its @@ -309,8 +259,9 @@ abstract class TraversableNode { enum CHILDREN_MOD { CREATED, REMOVED, MODIFIED } -typedef ChildrenModification = void Function( +typedef ChildrenModEventHandler = void Function( CHILDREN_MOD, List); +typedef ChildrenMod = void Function(T parent, List children); class AITVertex extends Vertex { AITVertex(T data) : super(data); From 14861ff9c848e53009406cde453b20d9a5420ca7 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 15 Aug 2021 21:26:21 -0600 Subject: [PATCH 304/404] WIP adding the nodes correctly into the tree after deserializing their nodes --- lib/eggs/custom_egg.dart | 4 ++-- .../layouts/temp_group_layout_node.dart | 17 +++++------------ .../subclasses/pb_intermediate_node.dart | 10 +++++++++- .../abstract_intermediate_node_factory.dart | 12 +++++++----- .../helpers/child_strategy.dart | 2 +- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 5e88cc49..87a253df 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -37,8 +37,8 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { var originalChildren = tree.childrenOf(originalRef); var egg = CustomEgg(originalRef.UUID, frame, originalRef.name.replaceAll('', '').pascalCase); - tree.addEdges( - AITVertex(this), originalChildren.map((e) => AITVertex(e)).toList()); + // tree.addEdges( + // AITVertex(this), originalChildren.map((e) => AITVertex(e)).toList()); return egg; } } diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index 125e0dfb..e810bdda 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -42,8 +42,8 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode }) : super(UUID, frame, [], [], name); @override - bool satisfyRules(PBContext context, - PBIntermediateNode currentNode, PBIntermediateNode nextNode) { + bool satisfyRules(PBContext context, PBIntermediateNode currentNode, + PBIntermediateNode nextNode) { assert(false, 'Attempted to satisfyRules for class type [$runtimeType]'); return null; } @@ -55,20 +55,13 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode return null; } - static PBIntermediateNode fromJson(Map json) { - var tempGroup = _$TempGroupLayoutNodeFromJson(json) - // . .frame.topLeft = Point.topLeftFromJson(json) - // . .frame.bottomRight = Point.bottomRightFromJson(json) - ..originalRef = json; - - //FIXME tempGroup.mapRawChildren(json); - - return tempGroup; - } + static PBIntermediateNode fromJson(Map json) => + _$TempGroupLayoutNodeFromJson(json); @override PBIntermediateNode createIntermediateNode(Map json, PBIntermediateNode parent, PBIntermediateTree tree) => (TempGroupLayoutNode.fromJson(json) as TempGroupLayoutNode) + ..mapRawChildren(json, tree) ..originalRef = json; } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 7b30a60b..57cd3c83 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -121,7 +121,9 @@ abstract class PBIntermediateNode //extends Iterable /// Returns true if there is an attribute in the node's `attributes` /// that matches `attributeName`. Returns false otherwise. bool hasAttribute(PBIntermediateTree tree, String attributeName) { - return tree.edges(AITVertex(this)).any((vertex) => vertex.data.attributeName == attributeName); + return tree + .edges(AITVertex(this)) + .any((vertex) => vertex.data.attributeName == attributeName); } /// Adds child to node. @@ -152,11 +154,17 @@ abstract class PBIntermediateNode //extends Iterable /// INFO: there might be a more straight fowards backtracking way of preventing these side effects. void align(PBContext context) { alignStrategy.align(context, this); + ///FIXME for (var currChild in children ?? []) { ///FIXME currChild?.align(context.clone()); ///FIXME } } + @override + String toString() { + return name ?? runtimeType; + } + factory PBIntermediateNode.fromJson(Map json, PBIntermediateNode parent, PBIntermediateTree tree) => AbstractIntermediateNodeFactory.getIntermediateNode(json, parent, tree); diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index 4aa14cf6..bb0d3703 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -51,15 +51,17 @@ class AbstractIntermediateNodeFactory { // Check if `iNode` is a tag //? If `iNode` is a tag, do we have to remove any links that \ //? may have been made during `createIntermediateNode()` ? - var egg = - PBPluginListHelper().returnAllowListNodeIfExists(iNode, tree); + var tag = null; + //PBPluginListHelper().returnAllowListNodeIfExists(iNode, tree); // Return tag if it exists - if (egg != null) { + if (tag != null) { + iNode.parent = parent; + tree.replaceNode(iNode, tag, acceptChildren: true); if (parent != null) { - tree.addEdges(Vertex(parent), [Vertex(egg)]); + tree.addEdges(Vertex(parent), [Vertex(tag)]); } - return egg; + return tag; } if (parent != null) { tree.addEdges(Vertex(parent), [Vertex(iNode)]); diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 3d759dbe..f55f9084 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -73,7 +73,7 @@ class TempChildrenStrategy extends ChildrenStrategy { addChild(group, targetChildren); group.frame = newFrame; } else if (targetChildren.isNotEmpty) { - var temp = TempGroupLayoutNode(null, null, name: children.name); + var temp = TempGroupLayoutNode(null, null, name: '${target.name}Group'); addChild(temp, targetChildren); var tempChildren = tree.childrenOf(temp); From 33e617ba2bf41888f09329c0c7dd6f5c17a4410f Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sun, 15 Aug 2021 23:21:40 -0500 Subject: [PATCH 305/404] Add edges of `target` to `replacement` on replaceNode(). Fix tag causing concurrent modification error. --- lib/eggs/custom_egg.dart | 6 +----- .../helpers/abstract_intermediate_node_factory.dart | 10 ++++------ .../helpers/pb_intermediate_node_tree.dart | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 87a253df..9a5341e7 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -34,12 +34,8 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { @override PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, PBIntermediateTree tree) { - var originalChildren = tree.childrenOf(originalRef); - var egg = CustomEgg(originalRef.UUID, frame, + return CustomEgg(originalRef.UUID, frame, originalRef.name.replaceAll('', '').pascalCase); - // tree.addEdges( - // AITVertex(this), originalChildren.map((e) => AITVertex(e)).toList()); - return egg; } } diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index bb0d3703..6e33ded6 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -51,15 +51,13 @@ class AbstractIntermediateNodeFactory { // Check if `iNode` is a tag //? If `iNode` is a tag, do we have to remove any links that \ //? may have been made during `createIntermediateNode()` ? - var tag = null; - //PBPluginListHelper().returnAllowListNodeIfExists(iNode, tree); + + var tag = + PBPluginListHelper().returnAllowListNodeIfExists(iNode, tree); // Return tag if it exists if (tag != null) { iNode.parent = parent; - tree.replaceNode(iNode, tag, acceptChildren: true); - if (parent != null) { - tree.addEdges(Vertex(parent), [Vertex(tag)]); - } + tree.replaceNode(iNode, tag, acceptChildren: false); return tag; } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 3de0a6ed..16f23e46 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -152,8 +152,7 @@ class PBIntermediateTree extends DirectedGraph { _childrenModObservers[UUID].forEach((listener) => listener( CHILDREN_MOD.CREATED, childrenVertices.map((e) => e.data))); } - return super.addEdges( - AITVertex(parent), childrenVertices); + return super.addEdges(AITVertex(parent), childrenVertices); }; parent.childrenStrategy.addChild(parent, children, addChildren, this); } @@ -198,6 +197,7 @@ class PBIntermediateTree extends DirectedGraph { addEdges(AITVertex(replacement), edges(AITVertex(target))); } remove(AITVertex(target)); + addEdges(AITVertex(target.parent), [AITVertex(target)]); return true; } From 84c347634c27ffb7fa21a89a65c234ebbfe40047 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Mon, 16 Aug 2021 12:49:20 -0500 Subject: [PATCH 306/404] Fix masters not being able to add override properties --- lib/controllers/interpret.dart | 2 +- .../entities/pb_shared_master_node.dart | 42 +++++++++++++++---- .../entities/pb_shared_master_node.g.dart | 21 +++------- .../subclasses/pb_intermediate_node.g.dart | 1 + .../helpers/pb_intermediate_node_tree.dart | 5 +++ .../helpers/pb_intermediate_node_tree.g.dart | 1 - lib/main.dart | 2 +- 7 files changed, 48 insertions(+), 26 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 5cbc94b0..28b21130 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -139,7 +139,7 @@ class AITServiceBuilder { try { if (transformation is AITNodeTransformation) { for (var node in _intermediateTree) { - node = await transformation(context, node, _intermediateTree); + node = await transformation(context, node.data, _intermediateTree); } } else if (transformation is AITTransformation) { _intermediateTree = await transformation(context, _intermediateTree); diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 77e2d08a..c4225caf 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -41,7 +41,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode Map parametersDefsMap = {}; ///The properties that could be be overridable on a [PBSharedMasterNode] - @JsonKey(name: 'overrideProperties') + @JsonKey(ignore: true) List overridableProperties; String friendlyName; @@ -89,20 +89,37 @@ class PBSharedMasterNode extends PBVisualIntermediateNode } static PBIntermediateNode fromJson(Map json) => - _$PBSharedMasterNodeFromJson(json) - ..originalRef = json; - // ..mapRawChildren(json); + _$PBSharedMasterNodeFromJson(json)..originalRef = json; @override PBIntermediateNode createIntermediateNode(Map json, - PBIntermediateNode parent, PBIntermediateTree tree) => - PBSharedMasterNode.fromJson(json)..mapRawChildren(json, tree); + PBIntermediateNode parent, PBIntermediateTree tree) { + var master = PBSharedMasterNode.fromJson(json)..mapRawChildren(json, tree); + + /// Map overridableProperties which need parent and tree + (master as PBSharedMasterNode).overridableProperties = + (json['overrideProperties'] as List) + ?.map( + (prop) => prop == null + ? null + : PBSharedParameterProp.createSharedParameter( + prop as Map, + parent, + tree, + ), + ) + ?.toList() ?? + []; + + return master; + } } @JsonSerializable() class PBSharedParameterProp { final String type; + @JsonKey(ignore: true) PBIntermediateNode value; @JsonKey(name: 'name', fromJson: _propertyNameFromJson) @@ -112,11 +129,22 @@ class PBSharedParameterProp { PBSharedParameterProp( this.type, - this.value, this.propertyName, this.UUID, ); + static PBSharedParameterProp createSharedParameter(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) { + var fromJson = PBSharedParameterProp.fromJson(json); + + // Populate `value` of Override Property since it is an [IntermediateNode] + fromJson.value = json['value'] == null + ? null + : PBIntermediateNode.fromJson(json, parent, tree); + + return fromJson; + } + factory PBSharedParameterProp.fromJson(Map json) => _$PBSharedParameterPropFromJson(json); diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart index 837beb0a..cb75de5f 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart @@ -13,11 +13,6 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { json['boundaryRectangle'] as Map), SYMBOL_ID: json['symbolID'] as String, name: json['name'] as String, - overridableProperties: (json['overrideProperties'] as List) - ?.map((e) => e == null - ? null - : PBSharedParameterProp.fromJson(e as Map)) - ?.toList(), prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) @@ -39,27 +34,21 @@ Map _$PBSharedMasterNodeToJson(PBSharedMasterNode instance) => 'prototypeNodeUUID': instance.prototypeNode?.toJson(), 'symbolID': instance.SYMBOL_ID, 'type': instance.type, - 'overrideProperties': - instance.overridableProperties?.map((e) => e?.toJson())?.toList(), }; PBSharedParameterProp _$PBSharedParameterPropFromJson( Map json) { - //FIXME // PBSharedParameterProp( - // json['type'] as String, - // json['value'] == null - // ? null - // : PBIntermediateNode.fromJson(json['value'] as Map), - // PBSharedParameterProp._propertyNameFromJson(json['name'] as String), - // json['UUID'] as String, - // ); + return PBSharedParameterProp( + json['type'] as String, + PBSharedParameterProp._propertyNameFromJson(json['name'] as String), + json['UUID'] as String, + ); } Map _$PBSharedParameterPropToJson( PBSharedParameterProp instance) => { 'type': instance.type, - 'value': instance.value, 'name': instance.propertyName, 'UUID': instance.UUID, }; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart index 79905b06..88070f6b 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart @@ -13,4 +13,5 @@ Map _$PBIntermediateNodeToJson(PBIntermediateNode instance) => 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, + 'hashCode': instance.hashCode, }; diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 16f23e46..9ddab0c2 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -29,6 +29,7 @@ class PBIntermediateTree extends DirectedGraph { String _UUID; String get UUID => _UUID; + @JsonKey(ignore: true) PBContext context; /// The [TREE_TYPE] of the [PBIntermediateTree]. @@ -102,6 +103,10 @@ class PBIntermediateTree extends DirectedGraph { @JsonKey(name: 'name') String get identifier => _identifier?.snakeCase ?? 'no_name_found'; + @override + @JsonKey(ignore: true) + Comparator> get comparator => super.comparator; + PBIntermediateTree({ String name, this.context, diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart index 4a3e298b..af205e40 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart @@ -14,6 +14,5 @@ PBIntermediateTree _$PBIntermediateTreeFromJson(Map json) { Map _$PBIntermediateTreeToJson(PBIntermediateTree instance) => { - 'designNode': instance.rootNode, 'name': instance.name, }; diff --git a/lib/main.dart b/lib/main.dart index 22ea066c..da27eec3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -130,7 +130,7 @@ ${parser.usage} tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); context.tree = tree; tree.context = context; - tree.forEach((node) => node.handleChildren(context)); + tree.forEach((node) => node.data.handleChildren(context)); return interpretService .interpretAndOptimize(tree, context, pbProject) .then((tree) => fpb.genAITree(tree, context)); From 00c0b0d5d5b5c4e336ab912111cd7e947f5ad050 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Mon, 16 Aug 2021 23:16:57 -0600 Subject: [PATCH 307/404] Refactored PBIntermediateNode to extend Vertex Co-authored-by: Ivan Co-authored-by: Bryan Figueroa --- lib/controllers/interpret.dart | 9 +- lib/eggs/injected_app_bar.dart | 10 +- lib/eggs/injected_tab.dart | 7 +- lib/eggs/injected_tab_bar.dart | 3 +- .../state_management_middleware.dart | 4 +- .../utils/middleware_utils.dart | 2 +- .../generators/symbols/pb_mastersym_gen.dart | 3 +- .../entities/style/figma_constraints.dart | 34 - .../entities/style/figma_constraints.g.dart | 63 -- .../helper/figma_constraint_to_pbdl.dart | 85 --- .../helper/sketch_constraint_to_pbdl.dart | 714 +++++++++--------- .../entities/inherited_scaffold.dart | 4 +- .../entities/inherited_text.dart | 2 +- .../entities/injected_container.dart | 1 - .../layouts/rules/container_rule.dart | 5 +- .../rules/stack_reduction_visual_rule.dart | 5 +- .../layouts/temp_group_layout_node.dart | 1 - .../entities/pb_shared_master_node.dart | 6 +- .../pb_intermediate_constraints.dart | 3 +- .../subclasses/pb_intermediate_node.dart | 48 +- .../pb_layout_intermediate_node.dart | 2 +- .../entities/subclasses/pbdl_constraints.dart | 22 - .../abstract_intermediate_node_factory.dart | 2 +- .../helpers/align_strategy.dart | 16 +- .../helpers/pb_intermediate_node_tree.dart | 57 +- .../pb_constraint_generation_service.dart | 5 +- .../pb_layout_generation_service.dart | 35 +- .../services/pb_symbol_linker_service.dart | 3 +- lib/main.dart | 3 +- pubspec.yaml | 1 + 30 files changed, 485 insertions(+), 670 deletions(-) delete mode 100644 lib/input/figma/entities/style/figma_constraints.dart delete mode 100644 lib/input/figma/entities/style/figma_constraints.g.dart delete mode 100644 lib/input/helper/figma_constraint_to_pbdl.dart delete mode 100644 lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 28b21130..20f3c748 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -138,8 +138,13 @@ class AITServiceBuilder { log.debug('Started running $name...'); try { if (transformation is AITNodeTransformation) { - for (var node in _intermediateTree) { - node = await transformation(context, node.data, _intermediateTree); + + for (var child in _intermediateTree) { + var dVertex = + await transformation(context, child, _intermediateTree); + if (dVertex.UUID != child.UUID) { + tree.replaceNode(child, dVertex); + } } } else if (transformation is AITTransformation) { _intermediateTree = await transformation(context, _intermediateTree); diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 39a4e26c..92b91111 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -54,8 +54,7 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { originalRef.name, ); var originalChildren = tree.childrenOf(originalRef); - tree.addEdges(AITVertex(appbar), - originalChildren.map((child) => AITVertex(child)).toList()); + tree.addEdges(appbar, originalChildren); return appbar; } @@ -82,7 +81,7 @@ class CustomAppBarAlignment extends AlignStrategy { middleItem.frame, name: middleItem.name, )..attributeName = 'title'; - context.tree.addEdges(AITVertex(tempNode), [AITVertex(middleItem)]); + context.tree.addEdges(tempNode, [middleItem]); } } @@ -97,10 +96,11 @@ class PBAppBarGenerator extends PBGenerator { buffer.write('AppBar('); - var children = generatorContext.tree.edges(AITVertex(source)); + var children = + generatorContext.tree.edges(source).cast(); children.forEach((child) { buffer.write( - '${child.data.attributeName}: ${_wrapOnBrackets(child.data.generator.generate(child.data, generatorContext), child == 'actions', child == 'leading')},'); + '${child.attributeName}: ${_wrapOnBrackets(child.generator.generate(child, generatorContext), child == 'actions', child == 'leading')},'); }); buffer.write(')'); diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 9a194a82..07849ec7 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -48,7 +48,7 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { if (originalNode is! TempGroupLayoutNode) { var designNode = _convertWrapper(originalNode); - tree.addEdges(AITVertex(this), [AITVertex(designNode)]); + tree.addEdges(this, [designNode]); } return tab; } @@ -91,9 +91,10 @@ class PBTabGenerator extends PBGenerator { if (source is Tab) { var buffer = StringBuffer(); buffer.write('BottomNavigationBarItem('); - var child = generatorContext.tree.edges(AITVertex(source)).first; + var child = + generatorContext.tree.edges(source).first as PBIntermediateNode; buffer.write(child != null - ? 'icon: ${child.data.generator.generate(child.data, generatorContext)}' + ? 'icon: ${child.generator.generate(child, generatorContext)}' : ''); buffer.write(')'); return buffer.toString(); diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index ccc1446c..97d6c688 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -60,8 +60,7 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { frame, originalRef.name, ); - tree.addEdges(AITVertex(tabbar), - originalChildren.map((child) => AITVertex(child)).toList()); + tree.addEdges(tabbar, originalChildren); return tabbar; } diff --git a/lib/generation/generators/middleware/state_management/state_management_middleware.dart b/lib/generation/generators/middleware/state_management/state_management_middleware.dart index fe82e025..8fb6f2ad 100644 --- a/lib/generation/generators/middleware/state_management/state_management_middleware.dart +++ b/lib/generation/generators/middleware/state_management/state_management_middleware.dart @@ -38,7 +38,9 @@ abstract class StateManagementMiddleware extends Middleware { } return Future.value(node); })).then((nodes) { - tree.rootNode = nodes.first; + if (nodes.isNotEmpty) { + tree.rootNode = nodes.first; + } return handleTree(tree.rootNode == null ? null : tree, context); }); } diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index d88f044c..738c7260 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -73,7 +73,7 @@ class MiddlewareUtils { ) { // Pass down manager data to states node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - // context.tree.data = node.managerData; + // context.tree = node.managerData; }); return ''' ${manager.generateImports()} diff --git a/lib/generation/generators/symbols/pb_mastersym_gen.dart b/lib/generation/generators/symbols/pb_mastersym_gen.dart index 5c89c6c3..d0fc6e94 100644 --- a/lib/generation/generators/symbols/pb_mastersym_gen.dart +++ b/lib/generation/generators/symbols/pb_mastersym_gen.dart @@ -12,7 +12,8 @@ class PBMasterSymbolGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext context) { context.sizingContext = SizingValueContext.LayoutBuilderValue; - var sourceChild = context.tree.childrenOf(source)?.first; + var children = context.tree.childrenOf(source); + var sourceChild = children.isNotEmpty ? children.first : null; var buffer = StringBuffer(); if (source is PBSharedMasterNode) { if (sourceChild == null) { diff --git a/lib/input/figma/entities/style/figma_constraints.dart b/lib/input/figma/entities/style/figma_constraints.dart deleted file mode 100644 index 54e7c1ae..00000000 --- a/lib/input/figma/entities/style/figma_constraints.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'figma_constraints.g.dart'; - -/// Defined by https://www.figma.com/plugin-docs/api/Constraints/ -@JsonSerializable(nullable: true) -class FigmaConstraints { - FigmaConstraints(this.horizontal, this.vertical); - FigmaConstraintType horizontal; - FigmaConstraintType vertical; - - factory FigmaConstraints.fromJson(Map json) => - _$FigmaConstraintsFromJson(json); - Map toJson() => _$FigmaConstraintsToJson(this); -} - -enum FigmaConstraintType { - @JsonValue('CENTER') - CENTER, - @JsonValue('TOP_BOTTOM') - TOP_BOTTOM, - @JsonValue('LEFT_RIGHT') - LEFT_RIGHT, - @JsonValue('SCALE') - SCALE, - @JsonValue('TOP') - TOP, - @JsonValue('BOTTOM') - BOTTOM, - @JsonValue('RIGHT') - RIGHT, - @JsonValue('LEFT') - LEFT -} diff --git a/lib/input/figma/entities/style/figma_constraints.g.dart b/lib/input/figma/entities/style/figma_constraints.g.dart deleted file mode 100644 index edabeab4..00000000 --- a/lib/input/figma/entities/style/figma_constraints.g.dart +++ /dev/null @@ -1,63 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'figma_constraints.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FigmaConstraints _$FigmaConstraintsFromJson(Map json) { - return FigmaConstraints( - _$enumDecodeNullable(_$FigmaConstraintTypeEnumMap, json['horizontal']), - _$enumDecodeNullable(_$FigmaConstraintTypeEnumMap, json['vertical']), - ); -} - -Map _$FigmaConstraintsToJson(FigmaConstraints instance) => - { - 'horizontal': _$FigmaConstraintTypeEnumMap[instance.horizontal], - 'vertical': _$FigmaConstraintTypeEnumMap[instance.vertical], - }; - -T _$enumDecode( - Map enumValues, - dynamic source, { - T unknownValue, -}) { - if (source == null) { - throw ArgumentError('A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}'); - } - - final value = enumValues.entries - .singleWhere((e) => e.value == source, orElse: () => null) - ?.key; - - if (value == null && unknownValue == null) { - throw ArgumentError('`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}'); - } - return value ?? unknownValue; -} - -T _$enumDecodeNullable( - Map enumValues, - dynamic source, { - T unknownValue, -}) { - if (source == null) { - return null; - } - return _$enumDecode(enumValues, source, unknownValue: unknownValue); -} - -const _$FigmaConstraintTypeEnumMap = { - FigmaConstraintType.CENTER: 'CENTER', - FigmaConstraintType.TOP_BOTTOM: 'TOP_BOTTOM', - FigmaConstraintType.LEFT_RIGHT: 'LEFT_RIGHT', - FigmaConstraintType.SCALE: 'SCALE', - FigmaConstraintType.TOP: 'TOP', - FigmaConstraintType.BOTTOM: 'BOTTOM', - FigmaConstraintType.RIGHT: 'RIGHT', - FigmaConstraintType.LEFT: 'LEFT', -}; diff --git a/lib/input/helper/figma_constraint_to_pbdl.dart b/lib/input/helper/figma_constraint_to_pbdl.dart deleted file mode 100644 index 446f5030..00000000 --- a/lib/input/helper/figma_constraint_to_pbdl.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'package:parabeac_core/input/figma/entities/style/figma_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; - -PBDLConstraints convertFigmaConstraintToPBDLConstraint( - FigmaConstraints figmaConstraints) { - var constraints = PBDLConstraints(); - constraints = - _convertFigmaConstraint(figmaConstraints.horizontal, constraints, false); - return _convertFigmaConstraint(figmaConstraints.vertical, constraints, true); -} - -/// Defined by https://www.figma.com/plugin-docs/api/Constraints/ -PBDLConstraints _convertFigmaConstraint(FigmaConstraintType figmaConstraintType, - PBDLConstraints constraints, bool isVertical) { - if (figmaConstraintType == FigmaConstraintType.SCALE) { - if (isVertical) { - constraints.pinTop = false; - constraints.pinBottom = false; - constraints.fixedHeight = false; - } else { - constraints.pinLeft = false; - constraints.pinRight = false; - constraints.fixedWidth = false; - } - } else if (figmaConstraintType == FigmaConstraintType.TOP) { - constraints.pinTop = true; - constraints.pinBottom = false; - constraints.fixedHeight = true; - } else if (figmaConstraintType == FigmaConstraintType.LEFT) { - constraints.pinLeft = true; - constraints.pinRight = false; - constraints.fixedWidth = true; - } else if (figmaConstraintType == FigmaConstraintType.RIGHT) { - constraints.pinLeft = false; - constraints.pinRight = true; - constraints.fixedWidth = true; - } else if (figmaConstraintType == FigmaConstraintType.BOTTOM) { - constraints.pinTop = false; - constraints.pinBottom = true; - constraints.fixedHeight = true; - } else if (figmaConstraintType == FigmaConstraintType.CENTER) { - if (isVertical) { - constraints.pinTop = false; - constraints.pinBottom = false; - constraints.fixedHeight = true; - } else { - constraints.pinLeft = false; - constraints.pinRight = false; - constraints.fixedWidth = true; - } - } else if (figmaConstraintType == FigmaConstraintType.TOP_BOTTOM) { - constraints.pinTop = true; - constraints.pinBottom = true; - constraints.fixedHeight = false; - } else if (figmaConstraintType == FigmaConstraintType.LEFT_RIGHT) { - constraints.pinLeft = true; - constraints.pinRight = true; - constraints.fixedWidth = false; - } else { - print( - 'We currently do not support Figma Constraint Type: $figmaConstraintType'); - } - return constraints; -} - -// } else if (figmaConstraintType == FigmaConstraintType.MIN) { -// if (isVertical) { -// constraints.pinTop = true; -// constraints.pinBottom = false; -// constraints.fixedHeight = false; -// } else { -// constraints.pinLeft = true; -// constraints.pinRight = false; -// constraints.fixedWidth = false; -// } -// } else if (figmaConstraintType == FigmaConstraintType.MAX) { -// if (isVertical) { -// constraints.pinTop = false; -// constraints.pinBottom = true; -// constraints.fixedHeight = false; -// } else { -// constraints.pinLeft = false; -// constraints.pinRight = true; -// constraints.fixedWidth = false; -// } diff --git a/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart b/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart index d89b3e37..936fdfe6 100644 --- a/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart +++ b/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart @@ -1,359 +1,359 @@ -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; +// import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; -PBDLConstraints convertSketchConstraintToPBDLConstraint( - int resizingConstraint) { - var constraints = sketchConstraintBitFieldToPBDLMap[resizingConstraint]; - if (constraints == null) { - print( - '[PBDL Conversion Error] We don\' support this `resizingConstraint` from Sketch.'); - } - return constraints; -} +// PBDLConstraints convertSketchConstraintToPBDLConstraint( +// int resizingConstraint) { +// var constraints = sketchConstraintBitFieldToPBDLMap[resizingConstraint]; +// if (constraints == null) { +// print( +// '[PBDL Conversion Error] We don\' support this `resizingConstraint` from Sketch.'); +// } +// return constraints; +// } -/// A map that references the Sketch Constraint Bitmap to PBDL Constraints. -/// For reference: https://www.notion.so/parabeac/2ff2c018c44644d9bba6bc4567f249c2?v=5c9a4978c96b4ee1aab8b219e3a2c006 -var sketchConstraintBitFieldToPBDLMap = { - 63: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: false, - pinBottom: false, - fixedHeight: false, - fixedWidth: false), - 18: PBDLConstraints( - pinLeft: true, - pinRight: true, - pinTop: true, - pinBottom: true, - fixedHeight: false, - fixedWidth: false), - 31: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: true, - pinBottom: false, - fixedHeight: false, - fixedWidth: false), - 27: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: true, - pinBottom: false, - fixedHeight: false, - fixedWidth: false), - 19: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: true, - pinBottom: true, - fixedHeight: false, - fixedWidth: false), - 22: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: true, - pinBottom: true, - fixedHeight: false, - fixedWidth: false), - 30: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: true, - pinBottom: false, - fixedHeight: false, - fixedWidth: false), - 26: PBDLConstraints( - pinLeft: true, - pinRight: true, - pinTop: true, - pinBottom: false, - fixedHeight: false, - fixedWidth: false), - 23: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: true, - pinBottom: true, - fixedHeight: false, - fixedWidth: false), - 59: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: false, - pinBottom: false, - fixedHeight: false, - fixedWidth: false), - 51: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: false, - pinBottom: true, - fixedHeight: false, - fixedWidth: false), - 50: PBDLConstraints( - pinLeft: true, - pinRight: true, - pinTop: false, - pinBottom: true, - fixedHeight: false, - fixedWidth: false), - 58: PBDLConstraints( - pinLeft: true, - pinRight: true, - pinTop: false, - pinBottom: false, - fixedHeight: false, - fixedWidth: false), - 55: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: false, - pinBottom: true, - fixedHeight: false, - fixedWidth: false), - 54: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: false, - pinBottom: true, - fixedHeight: false, - fixedWidth: false), - 62: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: false, - pinBottom: false, - fixedHeight: false, - fixedWidth: false), - 61: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: false, - pinBottom: false, - fixedHeight: false, - fixedWidth: true), - 29: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: true, - pinBottom: false, - fixedHeight: false, - fixedWidth: true), - 25: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: true, - pinBottom: false, - fixedHeight: false, - fixedWidth: true), - 17: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: true, - pinBottom: true, - fixedHeight: false, - fixedWidth: true), - 57: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: false, - pinBottom: false, - fixedHeight: false, - fixedWidth: true), - 49: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: false, - pinBottom: true, - fixedHeight: false, - fixedWidth: true), - 53: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: false, - pinBottom: true, - fixedHeight: false, - fixedWidth: true), - 52: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: false, - pinBottom: true, - fixedHeight: false, - fixedWidth: true), - 20: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: true, - pinBottom: true, - fixedHeight: false, - fixedWidth: true), - 60: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: false, - pinBottom: false, - fixedHeight: false, - fixedWidth: true), - 28: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: true, - pinBottom: false, - fixedHeight: false, - fixedWidth: true), - 21: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: true, - pinBottom: true, - fixedHeight: false, - fixedWidth: true), - 47: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: false, - pinBottom: false, - fixedHeight: true, - fixedWidth: false), - 15: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: true, - pinBottom: false, - fixedHeight: true, - fixedWidth: false), - 11: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: true, - pinBottom: false, - fixedHeight: true, - fixedWidth: false), - 43: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: false, - pinBottom: false, - fixedHeight: true, - fixedWidth: false), - 35: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: false, - pinBottom: true, - fixedHeight: true, - fixedWidth: false), - 34: PBDLConstraints( - pinLeft: true, - pinRight: true, - pinTop: false, - pinBottom: true, - fixedHeight: true, - fixedWidth: false), - 39: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: false, - pinBottom: true, - fixedHeight: true, - fixedWidth: false), - 38: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: false, - pinBottom: true, - fixedHeight: true, - fixedWidth: false), - 46: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: false, - pinBottom: false, - fixedHeight: true, - fixedWidth: false), - 14: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: true, - pinBottom: false, - fixedHeight: true, - fixedWidth: false), - 10: PBDLConstraints( - pinLeft: true, - pinRight: true, - pinTop: true, - pinBottom: false, - fixedHeight: true, - fixedWidth: false), - 42: PBDLConstraints( - pinLeft: true, - pinRight: true, - pinTop: false, - pinBottom: false, - fixedHeight: true, - fixedWidth: false), - 45: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: false, - pinBottom: false, - fixedHeight: true, - fixedWidth: true), - 13: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: true, - pinBottom: false, - fixedHeight: true, - fixedWidth: true), - 9: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: true, - pinBottom: false, - fixedHeight: true, - fixedWidth: true), - 41: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: false, - pinBottom: false, - fixedHeight: true, - fixedWidth: true), - 33: PBDLConstraints( - pinLeft: true, - pinRight: false, - pinTop: false, - pinBottom: true, - fixedHeight: true, - fixedWidth: true), - 37: PBDLConstraints( - pinLeft: false, - pinRight: false, - pinTop: false, - pinBottom: true, - fixedHeight: true, - fixedWidth: true), - 36: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: false, - pinBottom: true, - fixedHeight: true, - fixedWidth: true), - 44: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: false, - pinBottom: false, - fixedHeight: true, - fixedWidth: true), - 12: PBDLConstraints( - pinLeft: false, - pinRight: true, - pinTop: true, - pinBottom: false, - fixedHeight: true, - fixedWidth: true) -}; +// /// A map that references the Sketch Constraint Bitmap to PBDL Constraints. +// /// For reference: https://www.notion.so/parabeac/2ff2c018c44644d9bba6bc4567f249c2?v=5c9a4978c96b4ee1aab8b219e3a2c006 +// var sketchConstraintBitFieldToPBDLMap = { +// 63: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: false, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: false), +// 18: PBDLConstraints( +// pinLeft: true, +// pinRight: true, +// pinTop: true, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: false), +// 31: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: true, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: false), +// 27: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: true, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: false), +// 19: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: true, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: false), +// 22: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: true, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: false), +// 30: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: true, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: false), +// 26: PBDLConstraints( +// pinLeft: true, +// pinRight: true, +// pinTop: true, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: false), +// 23: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: true, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: false), +// 59: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: false, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: false), +// 51: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: false, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: false), +// 50: PBDLConstraints( +// pinLeft: true, +// pinRight: true, +// pinTop: false, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: false), +// 58: PBDLConstraints( +// pinLeft: true, +// pinRight: true, +// pinTop: false, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: false), +// 55: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: false, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: false), +// 54: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: false, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: false), +// 62: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: false, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: false), +// 61: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: false, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: true), +// 29: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: true, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: true), +// 25: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: true, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: true), +// 17: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: true, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: true), +// 57: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: false, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: true), +// 49: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: false, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: true), +// 53: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: false, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: true), +// 52: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: false, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: true), +// 20: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: true, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: true), +// 60: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: false, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: true), +// 28: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: true, +// pinBottom: false, +// fixedHeight: false, +// fixedWidth: true), +// 21: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: true, +// pinBottom: true, +// fixedHeight: false, +// fixedWidth: true), +// 47: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: false, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: false), +// 15: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: true, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: false), +// 11: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: true, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: false), +// 43: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: false, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: false), +// 35: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: false, +// pinBottom: true, +// fixedHeight: true, +// fixedWidth: false), +// 34: PBDLConstraints( +// pinLeft: true, +// pinRight: true, +// pinTop: false, +// pinBottom: true, +// fixedHeight: true, +// fixedWidth: false), +// 39: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: false, +// pinBottom: true, +// fixedHeight: true, +// fixedWidth: false), +// 38: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: false, +// pinBottom: true, +// fixedHeight: true, +// fixedWidth: false), +// 46: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: false, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: false), +// 14: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: true, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: false), +// 10: PBDLConstraints( +// pinLeft: true, +// pinRight: true, +// pinTop: true, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: false), +// 42: PBDLConstraints( +// pinLeft: true, +// pinRight: true, +// pinTop: false, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: false), +// 45: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: false, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: true), +// 13: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: true, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: true), +// 9: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: true, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: true), +// 41: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: false, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: true), +// 33: PBDLConstraints( +// pinLeft: true, +// pinRight: false, +// pinTop: false, +// pinBottom: true, +// fixedHeight: true, +// fixedWidth: true), +// 37: PBDLConstraints( +// pinLeft: false, +// pinRight: false, +// pinTop: false, +// pinBottom: true, +// fixedHeight: true, +// fixedWidth: true), +// 36: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: false, +// pinBottom: true, +// fixedHeight: true, +// fixedWidth: true), +// 44: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: false, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: true), +// 12: PBDLConstraints( +// pinLeft: false, +// pinRight: true, +// pinTop: true, +// pinBottom: false, +// fixedHeight: true, +// fixedWidth: true) +// }; diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 4cc6f773..626dd581 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -51,10 +51,10 @@ class InheritedScaffold extends PBVisualIntermediateNode var children = getAllAtrributeNamed(context.tree, 'body'); // Top-most stack should have scaffold's frame to align children properly var groupAtt = TempGroupLayoutNode(null, frame) + ..name = '$name-Group' ..attributeName = 'body' ..parent = this; - context.tree.addEdges(AITVertex(groupAtt), - children.map((child) => AITVertex(child)).toList()); + context.tree.addEdges(groupAtt, children.map((child) => child).toList()); // Keep appbar and tabbar var appBar = getAttributeNamed(context.tree, 'appBar'); diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index d27f63bd..952409e8 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -113,7 +113,7 @@ class InheritedText extends PBVisualIntermediateNode name: inheritedText.name, originalRef: json, ); - tree.addEdges(Vertex(container), [Vertex(inheritedText)]); + tree.addEdges(container, [inheritedText]); // Return an [InheritedContainer] that wraps this text return container; diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 4d234ae3..12afae16 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -8,7 +8,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; diff --git a/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart index 990426aa..ff420382 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/container_rule.dart @@ -36,7 +36,8 @@ class ContainerPostRule extends PostConditionRule { .firstWhere((element) => element is PBLayoutIntermediateNode), pbvisual = children .firstWhere((element) => element is PBVisualIntermediateNode); - return overlappingNodesLayoutRule.testRule(context, pbvisual, pblayout) && + return overlappingNodesLayoutRule.testRule( + context, pbvisual, pblayout) && tree.childrenOf(pbvisual).isNotEmpty; } } @@ -58,7 +59,7 @@ class ContainerPostRule extends PostConditionRule { .firstWhere((element) => element is PBLayoutIntermediateNode), pbvisual = layoutChildren .firstWhere((element) => element is PBVisualIntermediateNode); - tree.addEdges(AITVertex(pbvisual), [AITVertex(pblayout)]); + tree.addEdges(pbvisual, [pblayout]); //FIXME pbvisual.addChild(pblayout); layout = pbvisual; return layout; diff --git a/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart b/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart index 396f56a4..803dfc22 100644 --- a/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart +++ b/lib/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart @@ -32,7 +32,7 @@ class StackReductionVisualRule extends PostConditionRule { element is PBVisualIntermediateNode && currentTree.childrenOf(element).isEmpty); - currentTree.addEdges(AITVertex(wrapper), [AITVertex(child)]); + currentTree.addEdges(wrapper, [child]); if ((layout as PBIntermediateStackLayout).prototypeNode != null) { if (wrapper is PBInheritedIntermediate) { (wrapper as PBInheritedIntermediate).prototypeNode = @@ -64,7 +64,8 @@ class StackReductionVisualRule extends PostConditionRule { if (children.length == 2 && children[0] is PBVisualIntermediateNode && children[1] is PBVisualIntermediateNode) { - return _overlappingNodesLayoutRule.testRule(context, children[0], children[1]) && + return _overlappingNodesLayoutRule.testRule( + context, children[0], children[1]) && ((_isEmptyContainer(currTree, children[0]) && currTree.childrenOf(children[1]).isNotEmpty) || (_isEmptyContainer(currTree, children[0]) && diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index e810bdda..5d4acf07 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -5,7 +5,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index c4225caf..ff7bf6c9 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -85,7 +85,11 @@ class PBSharedMasterNode extends PBVisualIntermediateNode generator = PBMasterSymbolGenerator(); childrenStrategy = TempChildrenStrategy('child'); - overridableProperties.forEach(OverrideHelper.addProperty); + overridableProperties + + /// FIXME for some reason some of the elements are null + .where((element) => element != null) + .forEach(OverrideHelper.addProperty); } static PBIntermediateNode fromJson(Map json) => diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart index aab5fb84..c697f5bf 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart @@ -1,6 +1,5 @@ import 'dart:developer'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; /// Named PBDL in anticipation of the refactor where PBDL becomes the design standard. /// Each property must be set. @@ -25,7 +24,7 @@ class PBIntermediateConstraints { this.fixedWidth}); PBIntermediateConstraints.fromConstraints( - PBDLConstraints constraints, double height, double width) { + constraints, double height, double width) { pinLeft = constraints.pinLeft ?? false; pinRight = constraints.pinRight ?? false; pinTop = constraints.pinTop ?? false; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 57cd3c83..7ad5d634 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -24,7 +24,8 @@ part 'pb_intermediate_node.g.dart'; @JsonSerializable( explicitToJson: true, createFactory: false, ignoreUnannotated: true) -abstract class PBIntermediateNode //extends Iterable +abstract class PBIntermediateNode + extends Vertex //extends Iterable { @JsonKey(ignore: true) Logger logger; @@ -62,7 +63,7 @@ abstract class PBIntermediateNode //extends Iterable Rectangle frame; // @JsonKey(ignore: true) - // PBGenerationViewData get managerData => currentContext.tree.data; + // PBGenerationViewData get managerData => currentContext.tree; /// Auxillary Data of the node. Contains properties such as BorderInfo, Alignment, Color & a directed graph of states relating to this element. @JsonKey(name: 'style') @@ -73,7 +74,11 @@ abstract class PBIntermediateNode //extends Iterable String name; PBIntermediateNode(this._UUID, this.frame, this.name, - {this.subsemantic, this.constraints}) { + {this.subsemantic, this.constraints}) + : + + /// We are not using the [Vertex] attribute as it represents the [PBIntermediateNode] + super(null) { logger = Logger(runtimeType.toString()); if (_UUID == null) { logger.warning( @@ -87,19 +92,17 @@ abstract class PBIntermediateNode //extends Iterable /// null if the [PBAttribute] does not exist. PBIntermediateNode getAttributeNamed( PBIntermediateTree tree, String attributeName) { - return tree - .edges(AITVertex(this)) - .firstWhere((element) => element.data.attributeName == attributeName, - orElse: () => null) - ?.data; + return tree.edges(this).cast().firstWhere( + (child) => child.attributeName == attributeName, + orElse: () => null); } List getAllAtrributeNamed( PBIntermediateTree tree, String attributeName) { return tree - .edges(AITVertex(this)) - .where((element) => element.data.attributeName == attributeName) - .map((vertex) => vertex.data) + .edges(this) + .cast() + .where((child) => child.attributeName == attributeName) .toList(); } @@ -108,13 +111,14 @@ abstract class PBIntermediateNode //extends Iterable {bool allApperences = true}) { if (hasAttribute(tree, attributeName)) { tree.removeEdges( - AITVertex(this), + this, allApperences ? tree - .edges(AITVertex(this)) - .map((child) => child.data.attributeName = attributeName) - : tree.edges(AITVertex(this)).first); - tree.addEdges(AITVertex(this), [AITVertex(node)]); + .edges(this) + .cast() + .map((child) => child.attributeName = attributeName) + : tree.edges(this).first); + tree.addEdges(this, [node]); } } @@ -122,8 +126,9 @@ abstract class PBIntermediateNode //extends Iterable /// that matches `attributeName`. Returns false otherwise. bool hasAttribute(PBIntermediateTree tree, String attributeName) { return tree - .edges(AITVertex(this)) - .any((vertex) => vertex.data.attributeName == attributeName); + .edges(this) + .cast() + .any((child) => child.attributeName == attributeName); } /// Adds child to node. @@ -140,6 +145,13 @@ abstract class PBIntermediateNode //extends Iterable @override int get hashCode => UUID.hashCode; + @override + int get id => UUID.hashCode; + + @override + bool operator ==(Object other) => + other is PBIntermediateNode && other.id == id; + void handleChildren(PBContext context) {} /// In a recursive manner align the current [this] and the [children] of [this] diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index 2b9ee550..4c40e5dc 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -80,7 +80,7 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode void resize(PBContext context, [List children]) { children = - children ?? context.tree.edges(AITVertex(this)).map((e) => e.data); + children ?? context.tree.edges(this); if (children.isEmpty) { logger .warning('There should be children in the layout so it can resize.'); diff --git a/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart deleted file mode 100644 index ed75488f..00000000 --- a/lib/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart +++ /dev/null @@ -1,22 +0,0 @@ -/// Named PBDL in anticipation of the refactor where PBDL becomes the design standard. -/// Each property must be set, potentially use https://pub.dev/packages/meta to make these named parameters required. -class PBDLConstraints { - PBDLConstraints( - {this.pinLeft, - this.pinRight, - this.pinTop, - this.pinBottom, - this.fixedHeight, - this.fixedWidth}); - - /// - If all the pins are `false` thats just means is going to scale normally. - /// - If there is a pin value that is `true` we are going to use the constant value for that - /// attribute instead of the scaling value(using media query). - bool pinLeft; - bool pinRight; - bool pinTop; - bool pinBottom; - - bool fixedHeight; - bool fixedWidth; -} diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index 6e33ded6..a5024a05 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -62,7 +62,7 @@ class AbstractIntermediateNodeFactory { return tag; } if (parent != null) { - tree.addEdges(Vertex(parent), [Vertex(iNode)]); + tree.addEdges(parent, [iNode]); } return iNode; diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index d85c32dc..81b827c9 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -25,13 +25,13 @@ abstract class AlignStrategy { /// When [context.fixedWidth] is not `null`, se assign the [context.fixedWidth] to subtree and /// we make [node.constraints.pinLeft] = `true` and [node.constraints.pingRight] = `false`. void _setConstraints(PBContext context, T node) { - context.contextConstraints.fixedHeight ??= node.constraints.fixedHeight; - context.contextConstraints.fixedWidth ??= node.constraints.fixedWidth; + context.contextConstraints?.fixedHeight ??= node.constraints?.fixedHeight; + context.contextConstraints?.fixedWidth ??= node.constraints?.fixedWidth; if (context.contextConstraints.fixedHeight != null) { - node.constraints.fixedHeight = context.contextConstraints.fixedHeight; - node.constraints.pinTop = true; - node.constraints.pinBottom = false; + node.constraints?.fixedHeight = context.contextConstraints?.fixedHeight; + node.constraints?.pinTop = true; + node.constraints?.pinBottom = false; } if (context.contextConstraints.fixedWidth != null) { @@ -55,8 +55,8 @@ class PaddingAlignment extends AlignStrategy { top: (child.frame.topLeft.y - node.frame.topLeft.y).abs(), bottom: (child.frame.bottomRight.y - node.frame.bottomRight.y).abs(), ); - context.tree.addEdges(Vertex(padding), [Vertex(child)]); - context.tree.addEdges(Vertex(node), [Vertex(padding)]); + context.tree.addEdges(padding, [child]); + context.tree.addEdges(node, [padding]); super._setConstraints(context, node); } @@ -99,7 +99,7 @@ class PositionedAlignment extends AlignStrategy { width: child.frame.width, height: child.frame.height)); alignedChildren.add(injectedPositioned); - tree.addEdges(Vertex(injectedPositioned), [Vertex(child)]); + tree.addEdges(injectedPositioned, [child]); }); tree.replaceChildrenOf(node, alignedChildren); super._setConstraints(context, node); diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 9ddab0c2..b80dadd5 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -128,14 +128,13 @@ class PBIntermediateTree extends DirectedGraph { } List childrenOf(PBIntermediateNode node) => - edges(AITVertex(node)).map((e) => e.data).toList(); + edges(node).cast(); @override - void addEdges(Vertex parentVertex, - [List> childrenVertices]) { - var parent = parentVertex.data; - if (childrenVertices == null) {} - var children = childrenVertices.map((e) => e.data).toList(); + void addEdges(Vertex parent, + [List> children]) { + if (children == null) {} + // var children = childrenVertices.map((e) => e).toList(); /// Passing the responsability of acctually adding the [PBIntermediateNode] into /// the [tree] to the [parent.childStrategy]. The main reason for this is to enforce @@ -153,22 +152,23 @@ class PBIntermediateTree extends DirectedGraph { _elementStorage.elementToTree[child.UUID] = _UUID; } }); - if (_childrenModObservers.containsKey(parentVertex.data.UUID)) { - _childrenModObservers[UUID].forEach((listener) => listener( - CHILDREN_MOD.CREATED, childrenVertices.map((e) => e.data))); + if (_childrenModObservers.containsKey(parent.id)) { + _childrenModObservers[parent.id].forEach((listener) => listener( + CHILDREN_MOD.CREATED, children.toList())); } - return super.addEdges(AITVertex(parent), childrenVertices); + return super.addEdges(parent, children); }; - parent.childrenStrategy.addChild(parent, children, addChildren, this); + (parent as PBIntermediateNode) + .childrenStrategy + .addChild(parent, children.cast(), addChildren, this); } @override void removeEdges(Vertex parent, [List> children]) { - if (_childrenModObservers.containsKey(parent.data.UUID)) { - _childrenModObservers[UUID].forEach((listener) => listener( - CHILDREN_MOD.REMOVED, - children?.map((e) => e.data) ?? edges(parent).map((e) => e.data))); + if (_childrenModObservers.containsKey(parent.id)) { + _childrenModObservers[parent.id].forEach((listener) => listener( + CHILDREN_MOD.REMOVED, children?.toList() ?? edges(parent).toList())); } super.removeEdges(parent, children); } @@ -184,9 +184,9 @@ class PBIntermediateTree extends DirectedGraph { void replaceChildrenOf( PBIntermediateNode parent, List children) { - var parentVertex = AITVertex(parent); + var parentVertex = parent; removeEdges(parentVertex); - addEdges(parentVertex, children.map((child) => AITVertex(child)).toList()); + addEdges(parentVertex, children.toList()); } /// Replacing [target] with [replacement] @@ -199,10 +199,10 @@ class PBIntermediateTree extends DirectedGraph { throw Error(); } if (acceptChildren) { - addEdges(AITVertex(replacement), edges(AITVertex(target))); + addEdges(replacement, edges(target)); } - remove(AITVertex(target)); - addEdges(AITVertex(target.parent), [AITVertex(target)]); + remove(target); + addEdges(target.parent, [replacement]); return true; } @@ -229,7 +229,7 @@ class PBIntermediateTree extends DirectedGraph { PBIntermediateNode source, PBIntermediateNode target, ) => - shortestPath(Vertex(source), Vertex(target))?.length ?? -1; + shortestPath(source, target)?.length ?? -1; Map toJson() => _$PBIntermediateTreeToJson(this); @@ -237,7 +237,7 @@ class PBIntermediateTree extends DirectedGraph { var tree = _$PBIntermediateTreeFromJson(json); var designNode = PBIntermediateNode.fromJson(json['designNode'], null, tree); - tree.addEdges(Vertex(designNode), []); + tree.addEdges(designNode, []); tree._rootNode = designNode; return tree; @@ -268,19 +268,6 @@ typedef ChildrenModEventHandler = void Function( CHILDREN_MOD, List); typedef ChildrenMod = void Function(T parent, List children); -class AITVertex extends Vertex { - AITVertex(T data) : super(data); - - @override - int get id => data.UUID.hashCode; - - @override - int get hashCode => data.UUID.hashCode; - - @override - bool operator ==(Object other) => other is AITVertex && other.id == id; -} - TREE_TYPE treeTypeFromJson(Map json) { switch (json['type']) { case 'artboard': diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index 37287f2f..9815e43b 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -23,12 +23,13 @@ class PBConstraintGenerationService extends AITHandler { for (var node in tree.where((element) => element != null).toList().reversed) { + var child = tree.childrenOf(node)?.first; if (node.constraints == null) { - if (node.child?.constraints == null) { + if (child.constraints == null) { node.constraints = PBIntermediateConstraints( pinBottom: false, pinLeft: false, pinRight: false, pinTop: false); } else { - node.constraints = node.child.constraints; + node.constraints = child.constraints; } } } diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index c6019f79..58798852 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -111,20 +111,22 @@ class PBLayoutGenerationService extends AITHandler { /// Transforming the [TempGroupLayoutNode] into regular [PBLayoutIntermediateNode] void _transformGroup(PBIntermediateTree tree) { - tree.whereType().forEach((tempGroup) { - //FIXME // tree.replaceNode( - // tempGroup, - // PBIntermediateStackLayout( - // name: tempGroup.name, - // constraints: tempGroup.constraints, - // )..frame = tempGroup.frame, - // acceptChildren: true); + tree + .whereType() + .forEach((tempGroup) { + tree.replaceNode( + tempGroup, + PBIntermediateStackLayout( + name: tempGroup.name, + constraints: tempGroup.constraints, + )..frame = tempGroup.frame, + acceptChildren: true); }); } void _layoutTransformation(PBIntermediateTree tree, PBContext context) { for (var parent in tree) { - var children = parent.children; + var children = tree.childrenOf(parent); children.sort((n0, n1) => n0.frame.topLeft.compareTo(n1.frame.topLeft)); var childPointer = 0; @@ -146,20 +148,23 @@ class PBLayoutGenerationService extends AITHandler { ///then its going to use either one instead of creating a new [PBLayoutIntermediateNode]. if (layout.runtimeType == currentNode.runtimeType) { //FIXME tree.replaceNode(nextNode, currentNode); - currentNode.addChild(nextNode); + tree.addEdges(currentNode, [nextNode]); + tree.removeEdges(parent, [nextNode]); } else if (layout.runtimeType == nextNode.runtimeType) { //FIXME tree.replaceNode(currentNode, nextNode); - nextNode.addChild(currentNode); + tree.addEdges(nextNode, [currentNode]); + tree.removeEdges(parent, [currentNode]); } else { ///If neither of the current nodes are of the same `runtimeType` as the layout, we are going to use the actual ///satified [PBLayoutIntermediateNode] to generate the layout. We place both of the nodes inside ///of the generated layout. //FIXME tree.removeNode(currentNode, eliminateSubTree: true); //FIXME tree.removeNode(nextNode, eliminateSubTree: true); - parent.addChild(layout.generateLayout( - [currentNode, nextNode], - context, - '${currentNode.name}${nextNode.name}${layout.runtimeType}')); + tree.removeEdges(parent); + tree.addEdges(parent, [ + layout.generateLayout([currentNode, nextNode], context, + '${currentNode.name}${nextNode.name}${layout.runtimeType}') + ]); } reCheck = true; break; diff --git a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart index 25f000ce..5173b57a 100644 --- a/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_symbol_linker_service.dart @@ -27,7 +27,8 @@ class PBSymbolLinkerService extends AITHandler { return Future.value(tree); } - for (var node in tree) { + for (var vertex in tree) { + var node = vertex; if (node is PBSharedMasterNode) { await _symbolStorage.addSharedMasterNode(node); _aggregationService.gatherSharedParameters( diff --git a/lib/main.dart b/lib/main.dart index da27eec3..5bef315b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:math'; +import 'package:directed_graph/directed_graph.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; @@ -130,7 +131,7 @@ ${parser.usage} tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); context.tree = tree; tree.context = context; - tree.forEach((node) => node.data.handleChildren(context)); + tree.forEach((child) => child.handleChildren(context)); return interpretService .interpretAndOptimize(tree, context, pbProject) .then((tree) => fpb.genAITree(tree, context)); diff --git a/pubspec.yaml b/pubspec.yaml index 750573df..3ecd4453 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,6 +7,7 @@ environment: sdk: ">=2.7.0 <3.0.0" dependencies: + args: ^2.2.0 archive: ^3.1.2 json_serializable: ^3.5.0 build_runner: ^1.10.0 From 194038120be37c15ef3d28bd5d0effbd87f1c910 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Tue, 17 Aug 2021 14:24:50 -0500 Subject: [PATCH 308/404] Map PBDLConstraints to PBIntermedidateConstraints --- .../entities/inherited_circle.dart | 1 + .../entities/inherited_scaffold.dart | 1 + .../entities/inherited_text.dart | 1 + .../layouts/temp_group_layout_node.dart | 11 +++++-- .../entities/pb_shared_master_node.dart | 1 + .../pb_intermediate_constraints.dart | 32 +++++++++++-------- .../pb_intermediate_constraints.g.dart | 30 +++++++++++++++++ .../subclasses/pb_intermediate_node.dart | 1 + 8 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.g.dart diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 29d4ec73..c69f084a 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/intermediate_border_info.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 4cc6f773..abc5955b 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index d27f63bd..5f45fb73 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_text_gen.d import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index e810bdda..6bcf4584 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -39,7 +39,8 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode this.originalRef, String name, this.prototypeNode, - }) : super(UUID, frame, [], [], name); + PBIntermediateConstraints constraints, + }) : super(UUID, frame, [], [], name, constraints: constraints); @override bool satisfyRules(PBContext context, PBIntermediateNode currentNode, @@ -55,8 +56,12 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode return null; } - static PBIntermediateNode fromJson(Map json) => - _$TempGroupLayoutNodeFromJson(json); + static PBIntermediateNode fromJson(Map json) { + var tempGroup = _$TempGroupLayoutNodeFromJson(json); + tempGroup.constraints = PBIntermediateConstraints.fromConstraints( + json['constraints'], tempGroup.frame.height, tempGroup.frame.width); + return tempGroup; + } @override PBIntermediateNode createIntermediateNode(Map json, diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index c4225caf..522a4d26 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/generation/generators/symbols/pb_mastersym_gen.dar import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart index aab5fb84..f4d24fbb 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart @@ -1,10 +1,14 @@ import 'dart:developer'; +import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; +part 'pb_intermediate_constraints.g.dart'; + /// Named PBDL in anticipation of the refactor where PBDL becomes the design standard. /// Each property must be set. /// TODO: Use https://pub.dev/packages/meta to make these named parameters required. +@JsonSerializable() class PBIntermediateConstraints { bool pinLeft; bool pinRight; @@ -24,19 +28,21 @@ class PBIntermediateConstraints { this.fixedHeight, this.fixedWidth}); - PBIntermediateConstraints.fromConstraints( - PBDLConstraints constraints, double height, double width) { - pinLeft = constraints.pinLeft ?? false; - pinRight = constraints.pinRight ?? false; - pinTop = constraints.pinTop ?? false; - pinBottom = constraints.pinBottom ?? false; - if (constraints.fixedHeight) { - fixedHeight = height; - } - if (constraints.fixedWidth) { - fixedWidth = width; - } - } + factory PBIntermediateConstraints.fromConstraints( + Map json, double height, double width) => + PBIntermediateConstraints( + pinLeft: json['pinLeft'], + pinRight: json['pinRight'], + pinTop: json['pinTop'], + pinBottom: json['pinBottom'], + fixedHeight: json['fixedHeight'] ? height : null, + fixedWidth: json['fixedWidth'] ? width : null, + ); + + factory PBIntermediateConstraints.fromJson(Map json) => + _$PBIntermediateConstraintsFromJson(json); + + Map toJson() => _$PBIntermediateConstraintsToJson(this); PBIntermediateConstraints clone() { return PBIntermediateConstraints( diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.g.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.g.dart new file mode 100644 index 00000000..813b13cb --- /dev/null +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'pb_intermediate_constraints.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PBIntermediateConstraints _$PBIntermediateConstraintsFromJson( + Map json) { + return PBIntermediateConstraints( + pinLeft: json['pinLeft'] as bool, + pinRight: json['pinRight'] as bool, + pinTop: json['pinTop'] as bool, + pinBottom: json['pinBottom'] as bool, + fixedHeight: (json['fixedHeight'] as num)?.toDouble(), + fixedWidth: (json['fixedWidth'] as num)?.toDouble(), + ); +} + +Map _$PBIntermediateConstraintsToJson( + PBIntermediateConstraints instance) => + { + 'pinLeft': instance.pinLeft, + 'pinRight': instance.pinRight, + 'pinTop': instance.pinTop, + 'pinBottom': instance.pinBottom, + 'fixedHeight': instance.fixedHeight, + 'fixedWidth': instance.fixedWidth, + }; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 57cd3c83..10e8e77c 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -4,6 +4,7 @@ import 'dart:math'; import 'package:directed_graph/directed_graph.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; From 1e7fe74e2d1465829959d5f2e73a7bf3680cd521 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 17 Aug 2021 14:28:10 -0600 Subject: [PATCH 309/404] MOVED the Constraints desearilization & interpretation to the PBDL package. --- .../entities/inherited_bitmap.g.dart | 5 + .../entities/inherited_circle.g.dart | 7 +- .../entities/inherited_container.g.dart | 5 + .../entities/inherited_oval.g.dart | 7 +- .../entities/inherited_polygon.g.dart | 7 +- .../entities/inherited_scaffold.g.dart | 7 +- .../entities/inherited_shape_group.g.dart | 7 +- .../entities/inherited_shape_path.g.dart | 7 +- .../entities/inherited_star.g.dart | 7 +- .../entities/inherited_text.g.dart | 5 + .../entities/inherited_triangle.g.dart | 5 + .../entities/injected_container.g.dart | 7 +- .../layouts/temp_group_layout_node.dart | 4 +- .../layouts/temp_group_layout_node.g.dart | 7 +- .../entities/pb_shared_instance.g.dart | 7 +- .../entities/pb_shared_master_node.g.dart | 7 +- .../pb_intermediate_constraints.dart | 116 +++++++++--------- .../pb_intermediate_constraints.g.dart | 4 +- .../subclasses/pb_intermediate_node.dart | 3 +- .../subclasses/pb_intermediate_node.g.dart | 2 + .../pb_constraint_generation_service.dart | 54 ++++---- 21 files changed, 170 insertions(+), 110 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart index a493573a..b09cbd40 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart @@ -17,6 +17,10 @@ InheritedBitmap _$InheritedBitmapFromJson(Map json) { json['prototypeNodeUUID'] as String), ) ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -28,6 +32,7 @@ Map _$InheritedBitmapToJson(InheritedBitmap instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_circle.g.dart b/lib/interpret_and_optimize/entities/inherited_circle.g.dart index 4300208a..23114e96 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.g.dart @@ -15,7 +15,10 @@ InheritedCircle _$InheritedCircleFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -25,8 +28,8 @@ InheritedCircle _$InheritedCircleFromJson(Map json) { Map _$InheritedCircleToJson(InheritedCircle instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_container.g.dart b/lib/interpret_and_optimize/entities/inherited_container.g.dart index 910f9dc0..98791fb7 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.g.dart @@ -17,6 +17,10 @@ InheritedContainer _$InheritedContainerFromJson(Map json) { json['prototypeNodeUUID'] as String), ) ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -28,6 +32,7 @@ Map _$InheritedContainerToJson(InheritedContainer instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_oval.g.dart b/lib/interpret_and_optimize/entities/inherited_oval.g.dart index 769305a4..0701a0ee 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.g.dart @@ -15,7 +15,10 @@ InheritedOval _$InheritedOvalFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -25,8 +28,8 @@ InheritedOval _$InheritedOvalFromJson(Map json) { Map _$InheritedOvalToJson(InheritedOval instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart index 99f3cb96..38ab83ae 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart @@ -15,7 +15,10 @@ InheritedPolygon _$InheritedPolygonFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -25,8 +28,8 @@ InheritedPolygon _$InheritedPolygonFromJson(Map json) { Map _$InheritedPolygonToJson(InheritedPolygon instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart index 30544970..09ca89d5 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart @@ -17,7 +17,10 @@ InheritedScaffold _$InheritedScaffoldFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -27,8 +30,8 @@ InheritedScaffold _$InheritedScaffoldFromJson(Map json) { Map _$InheritedScaffoldToJson(InheritedScaffold instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart index 9c60bc07..4d641982 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart @@ -15,7 +15,10 @@ InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -26,8 +29,8 @@ InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { Map _$InheritedShapeGroupToJson( InheritedShapeGroup instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart index 1390b8d2..df5c2758 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart @@ -15,7 +15,10 @@ InheritedShapePath _$InheritedShapePathFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -25,8 +28,8 @@ InheritedShapePath _$InheritedShapePathFromJson(Map json) { Map _$InheritedShapePathToJson(InheritedShapePath instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_star.g.dart b/lib/interpret_and_optimize/entities/inherited_star.g.dart index 4ffe3b1b..3087cb79 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.g.dart @@ -15,7 +15,10 @@ InheritedStar _$InheritedStarFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -25,8 +28,8 @@ InheritedStar _$InheritedStarFromJson(Map json) { Map _$InheritedStarToJson(InheritedStar instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_text.g.dart b/lib/interpret_and_optimize/entities/inherited_text.g.dart index d3c358e5..ea119993 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.g.dart @@ -18,6 +18,10 @@ InheritedText _$InheritedTextFromJson(Map json) { text: json['content'] as String, ) ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -29,6 +33,7 @@ Map _$InheritedTextToJson(InheritedText instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart index 4537201e..8d869097 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart @@ -16,6 +16,10 @@ InheritedTriangle _$InheritedTriangleFromJson(Map json) { json['prototypeNodeUUID'] as String), ) ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -27,6 +31,7 @@ Map _$InheritedTriangleToJson(InheritedTriangle instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/injected_container.g.dart b/lib/interpret_and_optimize/entities/injected_container.g.dart index ed0f3e6d..f3eab2ee 100644 --- a/lib/interpret_and_optimize/entities/injected_container.g.dart +++ b/lib/interpret_and_optimize/entities/injected_container.g.dart @@ -16,7 +16,10 @@ InjectedContainer _$InjectedContainerFromJson(Map json) { PrototypeNode.prototypeNodeFromJson(json['prototypeNode'] as String), type: json['type'] as String, ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -25,8 +28,8 @@ InjectedContainer _$InjectedContainerFromJson(Map json) { Map _$InjectedContainerToJson(InjectedContainer instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart index 86e0b13c..54715416 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart @@ -57,8 +57,8 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode static PBIntermediateNode fromJson(Map json) { var tempGroup = _$TempGroupLayoutNodeFromJson(json); - tempGroup.constraints = PBIntermediateConstraints.fromConstraints( - json['constraints'], tempGroup.frame.height, tempGroup.frame.width); + // tempGroup.constraints = PBIntermediateConstraints.fromConstraints( + // json['constraints'], tempGroup.frame.height, tempGroup.frame.width); return tempGroup; } diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart index f6ad8850..200a0ed0 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart @@ -14,8 +14,11 @@ TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), + constraints: json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map), ) - ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -26,8 +29,8 @@ TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { Map _$TempGroupLayoutNodeToJson( TempGroupLayoutNode instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints?.toJson(), 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart index 34715b23..6fc03f7b 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart @@ -22,7 +22,10 @@ PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( json['prototypeNodeUUID'] as String), name: json['name'] as String, ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -33,8 +36,8 @@ PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( Map _$PBSharedInstanceIntermediateNodeToJson( PBSharedInstanceIntermediateNode instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints?.toJson(), 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart index cb75de5f..bbf08daf 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart @@ -16,7 +16,10 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) - ..subsemantic = json['subsemantic'] as String + ..constraints = json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map) ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -26,8 +29,8 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { Map _$PBSharedMasterNodeToJson(PBSharedMasterNode instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints?.toJson(), 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart index 255d8cbc..5d7e39d7 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart @@ -1,4 +1,3 @@ -import 'dart:developer'; import 'package:json_annotation/json_annotation.dart'; @@ -15,28 +14,28 @@ class PBIntermediateConstraints { bool pinBottom; /// If value is null, then the height is not fixed. - double fixedHeight; + bool fixedHeight; /// If value is null, then the width is not fixed. - double fixedWidth; + bool fixedWidth; PBIntermediateConstraints( - {this.pinLeft, - this.pinRight, - this.pinTop, - this.pinBottom, - this.fixedHeight, - this.fixedWidth}); + {this.pinLeft = false, + this.pinRight = false, + this.pinTop = false, + this.pinBottom = false, + this.fixedHeight = false, + this.fixedWidth = false}); - factory PBIntermediateConstraints.fromConstraints( - Map json, double height, double width) => - PBIntermediateConstraints( - pinLeft: json['pinLeft'], - pinRight: json['pinRight'], - pinTop: json['pinTop'], - pinBottom: json['pinBottom'], - fixedHeight: json['fixedHeight'] ? height : null, - fixedWidth: json['fixedWidth'] ? width : null, - ); + // factory PBIntermediateConstraints.fromConstraints( + // Map json, double height, double width) => + // PBIntermediateConstraints( + // pinLeft: json['pinLeft'], + // pinRight: json['pinRight'], + // pinTop: json['pinTop'], + // pinBottom: json['pinBottom'], + // fixedHeight: json['fixedHeight'] ? height : null, + // fixedWidth: json['fixedWidth'] ? width : null, + // ); factory PBIntermediateConstraints.fromJson(Map json) => _$PBIntermediateConstraintsFromJson(json); @@ -53,45 +52,52 @@ class PBIntermediateConstraints { fixedWidth: fixedWidth); } - PBIntermediateConstraints.mergeFromContraints( + factory PBIntermediateConstraints.mergeFromContraints( PBIntermediateConstraints first, PBIntermediateConstraints second) { - pinTop = (first.pinTop || second.pinTop) ? true : false; - pinLeft = (first.pinLeft || second.pinLeft) ? true : false; - pinRight = (first.pinRight || second.pinRight) ? true : false; - pinBottom = (first.pinBottom || second.pinBottom) ? true : false; + return PBIntermediateConstraints( + pinTop: first.pinTop || second.pinTop, + pinLeft: (first.pinLeft || second.pinLeft), + pinRight: (first.pinRight || second.pinRight), + pinBottom: (first.pinBottom || second.pinBottom), + fixedHeight: first.fixedHeight || second.fixedHeight, + fixedWidth: first.fixedWidth || second.fixedWidth); + // pinTop = (first.pinTop || second.pinTop) ? true : false; + // pinLeft = (first.pinLeft || second.pinLeft) ? true : false; + // pinRight = (first.pinRight || second.pinRight) ? true : false; + // pinBottom = (first.pinBottom || second.pinBottom) ? true : false; - /// Set Fixed Height Value - if (first.fixedHeight != null || second.fixedHeight != null) { - if (first.fixedHeight != null && second.fixedHeight != null) { - if (first.fixedHeight != second.fixedHeight) { - log('PBIntermediatConstraints tried merging constraints where fixed height & fixed height were both set & not equal.'); - fixedHeight = first.fixedHeight; - } else { - fixedHeight = first.fixedHeight; - } - } - if (first.fixedHeight == null) { - fixedHeight = second.fixedHeight; - } else { - fixedHeight = first.fixedHeight; - } - } + // /// Set Fixed Height Value + // if (first.fixedHeight != null || second.fixedHeight != null) { + // if (first.fixedHeight != null && second.fixedHeight != null) { + // if (first.fixedHeight != second.fixedHeight) { + // log('PBIntermediatConstraints tried merging constraints where fixed height & fixed height were both set & not equal.'); + // fixedHeight = first.fixedHeight; + // } else { + // fixedHeight = first.fixedHeight; + // } + // } + // if (first.fixedHeight == null) { + // fixedHeight = second.fixedHeight; + // } else { + // fixedHeight = first.fixedHeight; + // } + // } /// Set Fixed Width Value - if (first.fixedWidth != null || second.fixedWidth != null) { - if (first.fixedWidth != null && second.fixedWidth != null) { - if (first.fixedWidth != second.fixedWidth) { - log('PBIntermediatConstraints tried merging constraints where fixed width & fixed width were both set & not equal.'); - fixedWidth = first.fixedHeight; - } else { - fixedWidth = first.fixedHeight; - } - } - if (first.fixedWidth == null) { - fixedWidth = second.fixedWidth; - } else { - fixedWidth = first.fixedWidth; - } - } + // if (first.fixedWidth != null || second.fixedWidth != null) { + // if (first.fixedWidth != null && second.fixedWidth != null) { + // if (first.fixedWidth != second.fixedWidth) { + // log('PBIntermediatConstraints tried merging constraints where fixed width & fixed width were both set & not equal.'); + // fixedWidth = first.fixedHeight; + // } else { + // fixedWidth = first.fixedHeight; + // } + // } + // if (first.fixedWidth == null) { + // fixedWidth = second.fixedWidth; + // } else { + // fixedWidth = first.fixedWidth; + // } + // } } } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.g.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.g.dart index 813b13cb..6b2aaf5f 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.g.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.g.dart @@ -13,8 +13,8 @@ PBIntermediateConstraints _$PBIntermediateConstraintsFromJson( pinRight: json['pinRight'] as bool, pinTop: json['pinTop'] as bool, pinBottom: json['pinBottom'] as bool, - fixedHeight: (json['fixedHeight'] as num)?.toDouble(), - fixedWidth: (json['fixedWidth'] as num)?.toDouble(), + fixedHeight: json['fixedHeight'] as bool, + fixedWidth: json['fixedWidth'] as bool, ); } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 5d6bba6d..05b5825b 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -4,7 +4,6 @@ import 'dart:math'; import 'package:directed_graph/directed_graph.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; @@ -44,7 +43,7 @@ abstract class PBIntermediateNode String get UUID => _UUID; String _UUID; - @JsonKey(ignore: true) + @JsonKey(ignore: false) PBIntermediateConstraints constraints; @JsonKey(ignore: true) diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart index 88070f6b..b6c6f75c 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart @@ -10,8 +10,10 @@ Map _$PBIntermediateNodeToJson(PBIntermediateNode instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, + 'constraints': instance.constraints?.toJson(), 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'hashCode': instance.hashCode, + 'id': instance.id, }; diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index 9815e43b..338ba813 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -123,33 +123,33 @@ class PBConstraintGenerationService extends AITHandler { PBIntermediateConstraints _inheritConstraintsFromChild( {PBIntermediateConstraints constraints, PBIntermediateConstraints childConstraints}) { - if (childConstraints.pinLeft) { - constraints.pinLeft = true; - } - if (childConstraints.pinRight) { - constraints.pinRight = true; - } - if (childConstraints.pinTop) { - constraints.pinTop = true; - } - if (childConstraints.pinBottom) { - constraints.pinBottom = true; - } - if (childConstraints.fixedHeight != null) { - if (constraints.fixedHeight == null) { - constraints.fixedHeight = childConstraints.fixedHeight; - } else if (constraints.fixedHeight < childConstraints.fixedHeight) { - constraints.fixedHeight = childConstraints.fixedHeight; - } - } - if (childConstraints.fixedWidth != null) { - if (constraints.fixedWidth == null) { - constraints.fixedWidth = childConstraints.fixedWidth; - } else if (constraints.fixedWidth < childConstraints.fixedWidth) { - constraints.fixedWidth = childConstraints.fixedWidth; - } - } - return constraints; + // if (childConstraints.pinLeft) { + // constraints.pinLeft = true; + // } + // if (childConstraints.pinRight) { + // constraints.pinRight = true; + // } + // if (childConstraints.pinTop) { + // constraints.pinTop = true; + // } + // if (childConstraints.pinBottom) { + // constraints.pinBottom = true; + // } + // if (childConstraints.fixedHeight != null) { + // if (constraints.fixedHeight == null) { + // constraints.fixedHeight = childConstraints.fixedHeight; + // } else if (constraints.fixedHeight < childConstraints.fixedHeight) { + // constraints.fixedHeight = childConstraints.fixedHeight; + // } + // } + // if (childConstraints.fixedWidth != null) { + // if (constraints.fixedWidth == null) { + // constraints.fixedWidth = childConstraints.fixedWidth; + // } else if (constraints.fixedWidth < childConstraints.fixedWidth) { + // constraints.fixedWidth = childConstraints.fixedWidth; + // } + // } + // return constraints; } @override From f2062a21f5216d99d86ae70ce3320490fdcaaa54 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 17 Aug 2021 14:53:40 -0600 Subject: [PATCH 310/404] WIP FIXED constraints usage across the generation & interpretation phase. --- lib/controllers/interpret.dart | 2 +- .../generators/visual-widgets/pb_container_gen.dart | 2 +- .../subclasses/pb_intermediate_constraints.dart | 10 +++++++++- .../entities/subclasses/pb_intermediate_node.dart | 5 +++++ lib/interpret_and_optimize/helpers/align_strategy.dart | 6 +++--- .../services/pb_constraint_generation_service.dart | 3 ++- 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 20f3c748..9da548b1 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -45,7 +45,7 @@ class Interpret { PBSymbolLinkerService(), // PBPluginControlService(), PBLayoutGenerationService(), - PBConstraintGenerationService(), + // PBConstraintGenerationService(), PBAlignGenerationService() ]; diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index c592d3bf..603364d5 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -29,7 +29,7 @@ class PBContainerGenerator extends PBGenerator { // buffer.write( // 'alignment: Alignment(${(source.auxiliaryData.alignment['alignX'] as double).toStringAsFixed(2)}, ${(source.auxiliaryData.alignment['alignY'] as double).toStringAsFixed(2)}),'); // } - var child = sourceChildren.first; + var child = sourceChildren.isEmpty ? null : sourceChildren.first; if (child != null) { child.frame = source.frame; // source.child.currentContext = source.currentContext; diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart index 5d7e39d7..faed1949 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart @@ -1,4 +1,3 @@ - import 'package:json_annotation/json_annotation.dart'; part 'pb_intermediate_constraints.g.dart'; @@ -40,6 +39,15 @@ class PBIntermediateConstraints { factory PBIntermediateConstraints.fromJson(Map json) => _$PBIntermediateConstraintsFromJson(json); + factory PBIntermediateConstraints.defaultConstraints() => + PBIntermediateConstraints( + pinBottom: false, + pinRight: false, + pinLeft: false, + pinTop: false, + fixedHeight: false, + fixedWidth: false); + Map toJson() => _$PBIntermediateConstraintsToJson(this); PBIntermediateConstraints clone() { diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 05b5825b..efac66f2 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -85,6 +85,11 @@ abstract class PBIntermediateNode 'Generating UUID for $runtimeType-$name as its UUID is null'); _UUID = Uuid().v4(); } + + if(constraints == null){ + logger.debug('Constraints are null for $runtimeType, assigning it default constraints'); + constraints = PBIntermediateConstraints.defaultConstraints(); + } // _attributes = []; } diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 81b827c9..473d0376 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -35,9 +35,9 @@ abstract class AlignStrategy { } if (context.contextConstraints.fixedWidth != null) { - node.constraints.fixedWidth = context.contextConstraints.fixedWidth; - node.constraints.pinLeft = true; - node.constraints.pinRight = false; + node.constraints?.fixedWidth = context.contextConstraints.fixedWidth; + node.constraints?.pinLeft = true; + node.constraints?.pinRight = false; } } } diff --git a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart index 338ba813..135ceca8 100644 --- a/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_constraint_generation_service.dart @@ -23,7 +23,8 @@ class PBConstraintGenerationService extends AITHandler { for (var node in tree.where((element) => element != null).toList().reversed) { - var child = tree.childrenOf(node)?.first; + var children = tree.childrenOf(node); + var child = children.isEmpty ? null : children.first; if (node.constraints == null) { if (child.constraints == null) { node.constraints = PBIntermediateConstraints( From cf2d9439c0de8645cc486d39b1786110c9b66b19 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Tue, 17 Aug 2021 16:58:57 -0500 Subject: [PATCH 311/404] Fix adding list of children to TempGroupLayoutNode --- .../helpers/child_strategy.dart | 37 +++++++++++++------ .../helpers/pb_intermediate_node_tree.dart | 1 - 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index f55f9084..24315a10 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -19,8 +19,8 @@ class OneChildStrategy extends ChildrenStrategy { : super(attributeName, overridable); @override - void addChild( - PBIntermediateNode target, dynamic child, ChildrenMod addChild, tree) { + void addChild(PBIntermediateNode target, dynamic child, + ChildrenMod addChild, tree) { if (child is PBIntermediateNode) { addChild(target, [child]); } else { @@ -35,8 +35,8 @@ class MultipleChildStrategy extends ChildrenStrategy { : super(attributeName, overridable); @override - void addChild( - PBIntermediateNode target, children, ChildrenMod addChild, tree) { + void addChild(PBIntermediateNode target, children, + ChildrenMod addChild, tree) { if (children is List) { addChild(target, children); } else if (children is PBIntermediateNode) { @@ -49,8 +49,8 @@ class NoChildStrategy extends ChildrenStrategy { NoChildStrategy([bool overridable]) : super('N/A', overridable); @override - void addChild( - PBIntermediateNode target, children, ChildrenMod addChild, tree) { + void addChild(PBIntermediateNode target, children, + ChildrenMod addChild, tree) { logger.warning( 'Tried adding ${children.runtimeType.toString()} to ${target.runtimeType.toString()}'); } @@ -61,18 +61,26 @@ class TempChildrenStrategy extends ChildrenStrategy { : super(attributeName, overwridable); @override - void addChild( - PBIntermediateNode target, children, ChildrenMod addChild, tree) { + void addChild(PBIntermediateNode target, children, + ChildrenMod addChild, tree) { var targetChildren = tree.childrenOf(target); var group = targetChildren.firstWhere( (element) => element is TempGroupLayoutNode, orElse: () => null); + // TempGroup is the only child inside `target` if (group != null && targetChildren.length == 1) { // Calculate new frame based on incoming child - var newFrame = group.frame.boundingBox(children.frame); + var newFrame; + if (children is List) { + newFrame = group.frame.boundingBox(children.first.frame); + } else { + newFrame = group.frame.boundingBox(children.frame); + } addChild(group, targetChildren); group.frame = newFrame; - } else if (targetChildren.isNotEmpty) { + } + // Have no TempGroupLayoutNode but `target` already has children + else if (targetChildren.isNotEmpty) { var temp = TempGroupLayoutNode(null, null, name: '${target.name}Group'); addChild(temp, targetChildren); @@ -85,9 +93,16 @@ class TempChildrenStrategy extends ChildrenStrategy { } temp.frame = frame; + tree.removeEdges(target); addChild(target, [temp]); - } else if (children is PBIntermediateNode) { + } + // Adding a single child to empty `target` + else if (children is PBIntermediateNode) { addChild(target, [children]); + } + // Adding a list of `children` + else if (children is List) { + addChild(target, children); } } } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index b80dadd5..b74a4f05 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -237,7 +237,6 @@ class PBIntermediateTree extends DirectedGraph { var tree = _$PBIntermediateTreeFromJson(json); var designNode = PBIntermediateNode.fromJson(json['designNode'], null, tree); - tree.addEdges(designNode, []); tree._rootNode = designNode; return tree; From 7acadb964121955063dfbab2039449ae15546fbb Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 17 Aug 2021 19:15:00 -0600 Subject: [PATCH 312/404] FIX symbols & REFACTOR the temp group strategy. The symbols where not being added because the rootNode of the tree was being modified while collecting the import information. The refactor in the child strategy were efforts to increase some redeability. Co-authored-by: Ivan --- .../state_management_middleware.dart | 3 -- .../helpers/child_strategy.dart | 50 ++++++++++--------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/state_management_middleware.dart b/lib/generation/generators/middleware/state_management/state_management_middleware.dart index 8fb6f2ad..af52da47 100644 --- a/lib/generation/generators/middleware/state_management/state_management_middleware.dart +++ b/lib/generation/generators/middleware/state_management/state_management_middleware.dart @@ -38,9 +38,6 @@ abstract class StateManagementMiddleware extends Middleware { } return Future.value(node); })).then((nodes) { - if (nodes.isNotEmpty) { - tree.rootNode = nodes.first; - } return handleTree(tree.rootNode == null ? null : tree, context); }); } diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 24315a10..6d8b6849 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -60,6 +60,22 @@ class TempChildrenStrategy extends ChildrenStrategy { TempChildrenStrategy(String attributeName, [bool overwridable]) : super(attributeName, overwridable); + /// Rezising the [target.frame] basedon on the total [children.frame] area. + void _resizeFrameBasedOn(var children, PBIntermediateNode target) { + assert(children != null); + if (children is List) { + target.frame ??= children.first.frame; + children.forEach( + (child) => target.frame = target.frame.boundingBox(child.frame)); + } else if (children is PBIntermediateNode) { + target.frame = target.frame.boundingBox(children.frame); + } + } + + bool _containsSingleGroup( + PBIntermediateNode group, List children) => + group is TempGroupLayoutNode && children.length == 1; + @override void addChild(PBIntermediateNode target, children, ChildrenMod addChild, tree) { @@ -67,41 +83,29 @@ class TempChildrenStrategy extends ChildrenStrategy { var group = targetChildren.firstWhere( (element) => element is TempGroupLayoutNode, orElse: () => null); + children = children is List ? children : [children]; + // TempGroup is the only child inside `target` - if (group != null && targetChildren.length == 1) { + if (_containsSingleGroup(group, children)) { // Calculate new frame based on incoming child - var newFrame; - if (children is List) { - newFrame = group.frame.boundingBox(children.first.frame); - } else { - newFrame = group.frame.boundingBox(children.frame); - } - addChild(group, targetChildren); - group.frame = newFrame; + _resizeFrameBasedOn(children, group); + addChild(group, children); } - // Have no TempGroupLayoutNode but `target` already has children + + /// Have no TempGroupLayoutNode but `target` already has children else if (targetChildren.isNotEmpty) { var temp = TempGroupLayoutNode(null, null, name: '${target.name}Group'); addChild(temp, targetChildren); + addChild(temp, children); - var tempChildren = tree.childrenOf(temp); + _resizeFrameBasedOn(targetChildren, temp); + _resizeFrameBasedOn(children, temp); - // Calculate bounding box from all children - var frame = tempChildren.first.frame; - for (var i = 1; i < tempChildren.length; i++) { - frame = frame.boundingBox(tempChildren[i].frame); - } - - temp.frame = frame; tree.removeEdges(target); addChild(target, [temp]); } // Adding a single child to empty `target` - else if (children is PBIntermediateNode) { - addChild(target, [children]); - } - // Adding a list of `children` - else if (children is List) { + else { addChild(target, children); } } From 53b6dc5f70ca47ddac91c3f67e8ab81545741bdb Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 17 Aug 2021 21:08:08 -0600 Subject: [PATCH 313/404] WIP FIX non-unique UUID on text and made progress on generating the positions. --- .../visual-widgets/pb_positioned_gen.dart | 8 ++--- .../pb_prototype_aggregation_service.dart | 4 +++ .../entities/inherited_text.dart | 4 +-- .../subclasses/pb_intermediate_node.dart | 11 +++---- .../abstract_intermediate_node_factory.dart | 3 +- .../helpers/align_strategy.dart | 7 ++--- .../helpers/child_strategy.dart | 29 +++++++++++++++++-- .../helpers/element_storage.dart | 2 +- .../helpers/pb_intermediate_node_tree.dart | 24 +++++++++------ .../pb_shared_aggregation_service.dart | 2 +- 10 files changed, 62 insertions(+), 32 deletions(-) diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 0cb37921..a917458d 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -27,10 +27,6 @@ class PBPositionedGenerator extends PBGenerator { var xAxisBoilerplate = boilerplate.item1; var yAxisBoilerplate = boilerplate.item2; - if (context.tree.first.name == 'ArtboardTRpinnoscale') { - print('asdf'); - } - /// Since the generation phase is going to run multiple times, we are going to have to /// create a copy/clone of the [PositionedValueHolder] instead of assigning the values /// directly to the [source.valueHolder]. This would causse the [source.valueHolder.getRatioPercentage] @@ -63,8 +59,8 @@ class PBPositionedGenerator extends PBGenerator { // valueHolder.bottom = // ratio(source.valueHolder.bottom, isHorizontal: false); - // valueHolder.height = ratio(source.height, isHorizontal: false); - // valueHolder.width = ratio(source.width, isHorizontal: true); + // valueHolder.height = ratio(source.frame.height, isHorizontal: false); + // valueHolder.width = ratio(source.frame.width, isHorizontal: true); } try { for (var attribute in positionalAtt) { diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index 1053d9a8..bd5f7628 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -81,6 +81,7 @@ class PBPrototypeAggregationService { iNode.frame, (iNode as PBInheritedIntermediate).prototypeNode, ); + context.tree.addEdges(iNode); //FIXME destHolder.addChild(iNode); return destHolder; } else if (iNode is PBLayoutIntermediateNode) { @@ -89,6 +90,7 @@ class PBPrototypeAggregationService { iNode.frame, iNode.prototypeNode, ); + context.tree.addEdges(iNode); //FIXME destHolder.addChild(iNode); return destHolder; } else if (iNode is InjectedContainer) { @@ -97,6 +99,7 @@ class PBPrototypeAggregationService { iNode.frame, iNode.prototypeNode, ); + context.tree.addEdges(iNode); //FIXME destHolder.addChild(iNode); return destHolder; } else if (iNode is Tab) { @@ -106,6 +109,7 @@ class PBPrototypeAggregationService { iNode.prototypeNode, ); context.tree.childrenOf(iNode).forEach((element) { + context.tree.addEdges(element); //FIXME destHolder.addChild(element); }); return destHolder; diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 0052b6db..6a9557a1 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -1,5 +1,4 @@ import 'dart:math'; -import 'package:directed_graph/directed_graph.dart'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_text_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; @@ -17,6 +16,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; +import 'package:uuid/uuid.dart'; part 'inherited_text.g.dart'; @@ -107,7 +107,7 @@ class InheritedText extends PBVisualIntermediateNode PBIntermediateNode parent, PBIntermediateTree tree) { var inheritedText = InheritedText.fromJson(json); var container = InheritedContainer( - inheritedText.UUID, + null, inheritedText.frame, // topLeftCorner: inheritedText .frame.topLeft, // bottomRightCorner: inheritedText .frame.bottomRight, diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index efac66f2..cd6afdb2 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -86,8 +86,9 @@ abstract class PBIntermediateNode _UUID = Uuid().v4(); } - if(constraints == null){ - logger.debug('Constraints are null for $runtimeType, assigning it default constraints'); + if (constraints == null) { + logger.debug( + 'Constraints are null for $runtimeType, assigning it default constraints'); constraints = PBIntermediateConstraints.defaultConstraints(); } // _attributes = []; @@ -172,9 +173,9 @@ abstract class PBIntermediateNode void align(PBContext context) { alignStrategy.align(context, this); - ///FIXME for (var currChild in children ?? []) { - ///FIXME currChild?.align(context.clone()); - ///FIXME } + for (var currChild in context.tree.childrenOf(this) ?? []) { + currChild?.align(context.clone()); + } } @override diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index a5024a05..f95e26c4 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -56,8 +56,9 @@ class AbstractIntermediateNodeFactory { PBPluginListHelper().returnAllowListNodeIfExists(iNode, tree); // Return tag if it exists if (tag != null) { + /// [iNode] needs a parent and has not been added to the [tree] by [tree.addEdges] iNode.parent = parent; - tree.replaceNode(iNode, tag, acceptChildren: false); + tree.replaceNode(iNode, tag, acceptChildren: true); return tag; } diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 473d0376..3ef7e47a 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -77,9 +77,7 @@ class PositionedAlignment extends AlignStrategy { var alignedChildren = []; var tree = context.tree; var nodeChildren = context.tree.childrenOf(node); - nodeChildren.skipWhile((att) { - var child = att; - + nodeChildren.skipWhile((child) { /// if they are the same size then there is no need for adjusting. if (child.frame.topLeft == node.frame.topLeft && child.frame.bottomRight == node.frame.bottomRight) { @@ -87,8 +85,7 @@ class PositionedAlignment extends AlignStrategy { return true; } return false; - }).forEach((att) { - var child = att; + }).forEach((child) { var injectedPositioned = InjectedPositioned(null, child.frame, constraints: child.constraints, valueHolder: PositionedValueHolder( diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 6d8b6849..264a936e 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -21,8 +21,33 @@ class OneChildStrategy extends ChildrenStrategy { @override void addChild(PBIntermediateNode target, dynamic child, ChildrenMod addChild, tree) { - if (child is PBIntermediateNode) { - addChild(target, [child]); + var candidate; + var targetChildren = tree.childrenOf(target); + + if (child is Iterable && child.isNotEmpty) { + if (child.length > 1) { + logger.warning( + 'Only considering the first child of ${child.runtimeType.toString()} since it can only add one child to ${target.runtimeType.toString()}'); + } + candidate = child.first; + } else if (child is PBIntermediateNode) { + candidate ??= child; + } + + if (targetChildren.contains(candidate)) { + logger.warning( + 'Tried adding ${candidate.runtimeType.toString()} again to ${target.runtimeType.toString()}'); + return; + } + + if (candidate is PBIntermediateNode) { + if (targetChildren.length > 1) { + logger.warning( + 'Replacing children of ${target.runtimeType.toString()} with ${candidate.runtimeType.toString()}'); + } + + /// replacing the children of [target] with the single element + tree.replaceChildrenOf(target, [candidate]); } else { logger.warning( 'Tried adding ${child.runtimeType.toString()} to ${target.runtimeType.toString()}'); diff --git a/lib/interpret_and_optimize/helpers/element_storage.dart b/lib/interpret_and_optimize/helpers/element_storage.dart index 74cae9a0..c777d2a1 100644 --- a/lib/interpret_and_optimize/helpers/element_storage.dart +++ b/lib/interpret_and_optimize/helpers/element_storage.dart @@ -3,7 +3,7 @@ import 'dart:collection'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; class ElementStorage { - static ElementStorage _elementStorageInstance = ElementStorage._internal(); + static final ElementStorage _elementStorageInstance = ElementStorage._internal(); /// This [Map] contains the [PBIntermediateNode.UUID] to [PBIntermediateTree.UUID]. /// diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index b74a4f05..50163680 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -153,14 +153,13 @@ class PBIntermediateTree extends DirectedGraph { } }); if (_childrenModObservers.containsKey(parent.id)) { - _childrenModObservers[parent.id].forEach((listener) => listener( - CHILDREN_MOD.CREATED, children.toList())); + _childrenModObservers[parent.id].forEach( + (listener) => listener(CHILDREN_MOD.CREATED, children.toList())); } return super.addEdges(parent, children); }; - (parent as PBIntermediateNode) - .childrenStrategy - .addChild(parent, children.cast(), addChildren, this); + (parent as PBIntermediateNode).childrenStrategy.addChild( + parent, children.cast(), addChildren, this); } @override @@ -184,9 +183,8 @@ class PBIntermediateTree extends DirectedGraph { void replaceChildrenOf( PBIntermediateNode parent, List children) { - var parentVertex = parent; - removeEdges(parentVertex); - addEdges(parentVertex, children.toList()); + removeEdges(parent); + addEdges(parent, children.toList()); } /// Replacing [target] with [replacement] @@ -199,7 +197,15 @@ class PBIntermediateTree extends DirectedGraph { throw Error(); } if (acceptChildren) { - addEdges(replacement, edges(target)); + /// In the eyes of the [PBIntermediateTree], two [PBIntermediateNodes] with the same [UUID] + /// are the same vertex, and thus have the same edges. Therefore we do not want to add more edges + /// pointing to the same children. We simply want to update the existing edges' pointers. + if (target.UUID == replacement.UUID) { + // Change pointers of `target`'s `children` to point to `replacement` + childrenOf(target).forEach((child) => child.parent = replacement); + } else { + addEdges(replacement, edges(target)); + } } remove(target); addEdges(target.parent, [replacement]); diff --git a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart index 3a508aec..2030ce29 100644 --- a/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart +++ b/lib/interpret_and_optimize/services/pb_shared_aggregation_service.dart @@ -100,7 +100,7 @@ class PBSharedInterAggregationService { var elementStorage = ElementStorage(); var masterTree = elementStorage .treeUUIDs[elementStorage.elementToTree[masterNode.UUID]]; - var tree = elementStorage.treeUUIDs[instanceIntermediateNode.UUID]; + var tree = elementStorage.treeUUIDs[elementStorage.elementToTree[instanceIntermediateNode.UUID]]; if (masterTree != tree) { tree.addDependent(masterTree); } From 6821c4217a2320a16d665d3a196a4eb1ec7ea755 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Tue, 17 Aug 2021 22:38:31 -0500 Subject: [PATCH 314/404] Add guards to prevent cycle when replacing nodes under `OneChildStrategy` --- lib/interpret_and_optimize/helpers/child_strategy.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 264a936e..e520f1e7 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -41,13 +41,17 @@ class OneChildStrategy extends ChildrenStrategy { } if (candidate is PBIntermediateNode) { + /// replacing the children of [target] with the single element if (targetChildren.length > 1) { logger.warning( 'Replacing children of ${target.runtimeType.toString()} with ${candidate.runtimeType.toString()}'); + tree.replaceChildrenOf(target, [candidate]); } - /// replacing the children of [target] with the single element - tree.replaceChildrenOf(target, [candidate]); + /// Adding [candidate] to [target] + else { + addChild(target, [candidate]); + } } else { logger.warning( 'Tried adding ${child.runtimeType.toString()} to ${target.runtimeType.toString()}'); From 67a013c795ae50b78dcbbda89518f57b33a1eaa7 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 18 Aug 2021 12:16:11 -0500 Subject: [PATCH 315/404] Giving correct attributeName to Appbar and Tabbar from scaffold. --- lib/eggs/injected_app_bar.dart | 7 +++++-- .../entities/inherited_scaffold.dart | 12 ++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 92b91111..6a9a8c45 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -53,8 +53,11 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { frame, originalRef.name, ); - var originalChildren = tree.childrenOf(originalRef); - tree.addEdges(appbar, originalChildren); + + tree.childrenOf(appbar).forEach((element) { + element.attributeName = getAttributeNameOf(element); + }); + return appbar; } diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 7a7fc7bb..5c442346 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -1,4 +1,6 @@ import 'dart:math'; +import 'package:parabeac_core/eggs/injected_app_bar.dart'; +import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; @@ -47,6 +49,16 @@ class InheritedScaffold extends PBVisualIntermediateNode childrenStrategy = MultipleChildStrategy('body'); } + @override + String getAttributeNameOf(PBIntermediateNode node) { + if (node is InjectedAppbar) { + return 'appBar'; + } else if (node is InjectedTabBar) { + return 'tabBar'; + } + return super.getAttributeNameOf(node); + } + @override void handleChildren(PBContext context) { var children = getAllAtrributeNamed(context.tree, 'body'); From 35a686088200a331f597276edd0aeeb1d52f9c5a Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 18 Aug 2021 12:25:02 -0500 Subject: [PATCH 316/404] Simplify `replaceNode` function --- .../helpers/pb_intermediate_node_tree.dart | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 50163680..926c1f70 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -196,18 +196,14 @@ class PBIntermediateTree extends DirectedGraph { if (target.parent == null) { throw Error(); } + + var children = childrenOf(target); + + remove(target); + if (acceptChildren) { - /// In the eyes of the [PBIntermediateTree], two [PBIntermediateNodes] with the same [UUID] - /// are the same vertex, and thus have the same edges. Therefore we do not want to add more edges - /// pointing to the same children. We simply want to update the existing edges' pointers. - if (target.UUID == replacement.UUID) { - // Change pointers of `target`'s `children` to point to `replacement` - childrenOf(target).forEach((child) => child.parent = replacement); - } else { - addEdges(replacement, edges(target)); - } + addEdges(replacement, children); } - remove(target); addEdges(target.parent, [replacement]); return true; } From 13f5e944c053b48e16f9c23266ecb6304f834dff Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 18 Aug 2021 12:58:23 -0500 Subject: [PATCH 317/404] Adding override properties to OverrideHelper --- .../entities/pb_shared_master_node.dart | 12 ++++++------ .../helpers/pb_intermediate_node_tree.dart | 16 ++++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 993cb74e..63dff0b9 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -85,12 +85,6 @@ class PBSharedMasterNode extends PBVisualIntermediateNode generator = PBMasterSymbolGenerator(); childrenStrategy = TempChildrenStrategy('child'); - - overridableProperties - - /// FIXME for some reason some of the elements are null - .where((element) => element != null) - .forEach(OverrideHelper.addProperty); } static PBIntermediateNode fromJson(Map json) => @@ -116,6 +110,12 @@ class PBSharedMasterNode extends PBVisualIntermediateNode ?.toList() ?? []; + // Add override properties to the [OverrideHelper] + (master as PBSharedMasterNode) + .overridableProperties + .where((element) => element != null) + .forEach((OverrideHelper.addProperty)); + return master; } } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 926c1f70..50163680 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -196,14 +196,18 @@ class PBIntermediateTree extends DirectedGraph { if (target.parent == null) { throw Error(); } - - var children = childrenOf(target); - - remove(target); - if (acceptChildren) { - addEdges(replacement, children); + /// In the eyes of the [PBIntermediateTree], two [PBIntermediateNodes] with the same [UUID] + /// are the same vertex, and thus have the same edges. Therefore we do not want to add more edges + /// pointing to the same children. We simply want to update the existing edges' pointers. + if (target.UUID == replacement.UUID) { + // Change pointers of `target`'s `children` to point to `replacement` + childrenOf(target).forEach((child) => child.parent = replacement); + } else { + addEdges(replacement, edges(target)); + } } + remove(target); addEdges(target.parent, [replacement]); return true; } From 4f3b02d8aa262a7d82b42bd8661b538464dee6f3 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 18 Aug 2021 12:43:25 -0600 Subject: [PATCH 318/404] WIP FIX pinning in the injected positioned. --- .../visual-widgets/pb_positioned_gen.dart | 83 +++++++++---------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index a917458d..8afffd1b 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -23,9 +23,9 @@ class PBPositionedGenerator extends PBGenerator { var buffer = StringBuffer('Positioned('); - var boilerplate = _getBoilerplate(context.sizingContext); - var xAxisBoilerplate = boilerplate.item1; - var yAxisBoilerplate = boilerplate.item2; + // var boilerplate = _getBoilerplate(context.sizingContext); + // var xAxisBoilerplate = boilerplate.item1; + // var yAxisBoilerplate = boilerplate.item2; /// Since the generation phase is going to run multiple times, we are going to have to /// create a copy/clone of the [PositionedValueHolder] instead of assigning the values @@ -41,7 +41,9 @@ class PBPositionedGenerator extends PBGenerator { width: source.valueHolder.width, height: source.valueHolder.height); - var positionalAtt = _getPositionalAtt(valueHolder, source.constraints); + var positionalAtt = _getPositionalAtt(valueHolder, source.constraints) + ..forEach((pos) => + pos.boilerplate = _getBoilerplate(context.sizingContext, pos)); if (!(context.sizingContext == SizingValueContext.PointValue)) { /// [SizingValueContext.PointValue] is the only value in which dont change based on another scale/sizing @@ -53,29 +55,12 @@ class PBPositionedGenerator extends PBGenerator { ratio(attribute.value, isHorizontal: attribute.isXAxis); } } - // valueHolder.left = ratio(source.valueHolder.left, isHorizontal: true); - // valueHolder.right = ratio(source.valueHolder.right, isHorizontal: true); - // valueHolder.top = ratio(source.valueHolder.top, isHorizontal: false); - // valueHolder.bottom = - // ratio(source.valueHolder.bottom, isHorizontal: false); - - // valueHolder.height = ratio(source.frame.height, isHorizontal: false); - // valueHolder.width = ratio(source.frame.width, isHorizontal: true); } try { for (var attribute in positionalAtt) { buffer.write( - '${attribute.attributeName}: ${_normalizeValue(attribute.isXAxis ? xAxisBoilerplate : yAxisBoilerplate, attribute)},'); + '${attribute.attributeName}: ${_normalizeValue(attribute.boilerplate, attribute)},'); } - // buffer.write( - // 'left: ${_normalizeValue(xAxisBoilerplate, valueHolder.left)}, top: ${_normalizeValue(yAxisBoilerplate, valueHolder.top)},'); - // if (overrideChildDim) { - // buffer.write( - // 'width: ${_normalizeValue(xAxisBoilerplate, valueHolder.width)}, height: ${_normalizeValue(yAxisBoilerplate, valueHolder.height)},'); - // } else { - // buffer.write( - // 'right: ${_normalizeValue(xAxisBoilerplate, valueHolder.right)}, bottom: ${_normalizeValue(yAxisBoilerplate, valueHolder.bottom)},'); - // } // source.child.currentContext = source.currentContext; buffer.write( @@ -93,16 +78,26 @@ class PBPositionedGenerator extends PBGenerator { } /// Getting the boilerplate needed to fill in the generation depending on the [sizingValueContext]. - Tuple2 _getBoilerplate( - SizingValueContext sizingValueContext) { - if (sizingValueContext == SizingValueContext.ScaleValue) { - return Tuple2('${PBGenerator.MEDIAQUERY_HORIZONTAL_BOILERPLATE} * ', - '${PBGenerator.MEDIAQUERY_VERTICAL_BOILERPLATE} * '); - } + String _getBoilerplate(SizingValueContext sizingValueContext, + _PositionedValue _positionedValue) { if (sizingValueContext == SizingValueContext.LayoutBuilderValue) { - return Tuple2('constraints.maxWidth * ', 'constraints.maxHeight * '); + if (_positionedValue.isXAxis) { + return 'constraints.maxWidth *'; + } else { + return 'constraints.maxHeight *'; + } + } + + if (_positionedValue.remainPointValue || + sizingValueContext != SizingValueContext.ScaleValue) { + return ''; + } + + if (_positionedValue.isXAxis) { + return '${PBGenerator.MEDIAQUERY_HORIZONTAL_BOILERPLATE} * '; + } else { + return '${PBGenerator.MEDIAQUERY_VERTICAL_BOILERPLATE} * '; } - return Tuple2('', ''); } /// Going to return the value without the [preValueStatement] if the [positionalValue] @@ -129,26 +124,24 @@ class PBPositionedGenerator extends PBGenerator { PositionedValueHolder positionedValueHolder, PBIntermediateConstraints constraints) { var attributes = <_PositionedValue>[]; - var fixedWidth = constraints.fixedWidth != null; - var fixedHeight = constraints.fixedHeight != null; if (!constraints.pinLeft && !constraints.pinRight) { ///use [positionedValueHolder.left] attributes .add(_PositionedValue(positionedValueHolder.left, 'left', false)); - attributes.add( - _PositionedValue(positionedValueHolder.width, 'width', fixedWidth)); + attributes.add(_PositionedValue( + positionedValueHolder.width, 'width', constraints.fixedWidth)); } else if (constraints.pinLeft && !constraints.pinRight) { ///use [positionedValueHolder.left] attributes .add(_PositionedValue(positionedValueHolder.left, 'left', true)); - attributes.add( - _PositionedValue(positionedValueHolder.width, 'width', fixedWidth)); + attributes.add(_PositionedValue( + positionedValueHolder.width, 'width', constraints.fixedWidth)); } else if (!constraints.pinLeft && constraints.pinRight) { /// use [positionedValueHolder.right] attributes .add(_PositionedValue(positionedValueHolder.right, 'right', true)); - attributes.add( - _PositionedValue(positionedValueHolder.width, 'width', fixedWidth)); + attributes.add(_PositionedValue( + positionedValueHolder.width, 'width', constraints.fixedWidth)); } else if (constraints.pinLeft && constraints.pinRight) { attributes .add(_PositionedValue(positionedValueHolder.left, 'left', true)); @@ -160,19 +153,19 @@ class PBPositionedGenerator extends PBGenerator { if (!constraints.pinTop && !constraints.pinBottom) { attributes.add( _PositionedValue(positionedValueHolder.top, 'top', false, false)); - attributes.add(_PositionedValue( - positionedValueHolder.height, 'height', fixedHeight, false)); + attributes.add(_PositionedValue(positionedValueHolder.height, 'height', + constraints.fixedHeight, false)); } else if (constraints.pinTop && !constraints.pinBottom) { attributes .add(_PositionedValue(positionedValueHolder.top, 'top', true, false)); - attributes.add(_PositionedValue( - positionedValueHolder.height, 'height', fixedHeight, false)); + attributes.add(_PositionedValue(positionedValueHolder.height, 'height', + constraints.fixedHeight, false)); } else if (!constraints.pinTop && constraints.pinBottom) { /// use [positionedValueHolder.right] attributes.add(_PositionedValue( positionedValueHolder.bottom, 'bottom', true, false)); - attributes.add(_PositionedValue( - positionedValueHolder.height, 'height', fixedHeight, false)); + attributes.add(_PositionedValue(positionedValueHolder.height, 'height', + constraints.fixedHeight, false)); } else if (constraints.pinTop && constraints.pinBottom) { attributes .add(_PositionedValue(positionedValueHolder.top, 'top', true, false)); @@ -187,6 +180,8 @@ class _PositionedValue { final String attributeName; final bool remainPointValue; final bool isXAxis; + + String boilerplate; double value; _PositionedValue(this.value, this.attributeName, this.remainPointValue, From f111166b4fde5c3a4ba9339d87b2658054340761 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 18 Aug 2021 21:59:59 -0600 Subject: [PATCH 319/404] WIP FIX the creation of the pubspec YAML file and the addition of its dependencies. --- .../flutter_project_builder.dart | 9 +++----- .../util/pb_generation_project_data.dart | 6 ++++-- .../pb_generation_configuration.dart | 21 ++++++++++--------- .../riverpod_generation_configuration.dart | 3 ++- .../generators/writers/pb_flutter_writer.dart | 15 +++---------- .../generators/writers/pb_page_writer.dart | 3 --- .../writers/pb_traversal_adapter_writer.dart | 8 +++---- 7 files changed, 27 insertions(+), 38 deletions(-) diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index 31e21437..39826af5 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; +import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:path/path.dart' as p; @@ -52,7 +53,7 @@ class FlutterProjectBuilder { log = Logger(runtimeType.toString()); fileSystemAnalyzer ??= FileSystemAnalyzer(project.projectAbsPath); - // generationConfiguration.pageWriter = pageWriter; + generationConfiguration.pageWriter = PBFlutterWriter(); generationConfiguration.fileSystemAnalyzer = fileSystemAnalyzer; } @@ -125,11 +126,6 @@ class FlutterProjectBuilder { ; } - Future postGenTask() async { - await formatProject(project.projectAbsPath, - projectDir: MainInfo().outputPath); - } - Future genAITree(PBIntermediateTree tree, PBContext context) async { if (!_configured) { /// Avoid changing the [_configured] from here, it might lead to async changes on the var @@ -139,6 +135,7 @@ class FlutterProjectBuilder { await generationConfiguration.generateTree(tree, project, context, true); await generationConfiguration.generateTree(tree, project, context, false); generationConfiguration.generatePlatformAndOrientationInstance(project); + await formatProject(project.projectAbsPath, projectDir: MainInfo().outputPath); } } diff --git a/lib/generation/generators/util/pb_generation_project_data.dart b/lib/generation/generators/util/pb_generation_project_data.dart index fb01d661..ac5ec846 100644 --- a/lib/generation/generators/util/pb_generation_project_data.dart +++ b/lib/generation/generators/util/pb_generation_project_data.dart @@ -1,7 +1,9 @@ +import 'dart:collection'; + import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; class PBGenerationProjectData { - void addDependencies(String packageName, String version) => - PBFlutterWriter().addDependency(packageName, version); + Map dependencies = {}; + void addDependencies(String packageName, String version) => dependencies[packageName] = version; } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 0b510038..f7d0cd99 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -51,8 +51,8 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { /// PageWriter to be used for generation PBPageWriter pageWriter = PBFlutterWriter(); - final Map _dependencies = {}; - Iterable> get dependencies => _dependencies.entries; + // final Map _dependencies = {}; + // Iterable> get dependencies => _dependencies.entries; /// List of observers that will be notified when a new command is added. final commandObservers = []; @@ -91,13 +91,15 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { /// that generate the code for each tree in the [trees]. Future generateTree(PBIntermediateTree tree, PBProject project, PBContext context, bool lockData) async { + var processInfo = MainInfo(); fileStructureStrategy.dryRunMode = lockData; tree.lockData = lockData; fileStructureStrategy.addImportsInfo(tree, context); context.generationManager = generationManager; generationManager.data = tree.generationViewData; - tree.generationViewData.addImport(FlutterImport('material.dart', 'flutter')); + tree.generationViewData + .addImport(FlutterImport('material.dart', 'flutter')); // Relative path to the file to create var relPath = p.join(tree.name.snakeCase, tree.identifier); @@ -111,11 +113,11 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await _setMainScreen(tree, relPath, MainInfo().projectName); } await applyMiddleware(tree, context); + await _commitDependencies(processInfo.genProjectPath, project); } ///Generates the [PBIntermediateTree]s within the [pb_project] Future generateProject(PBProject pb_project) async { - var processInfo = MainInfo(); _head = CommandGenMiddleware( generationManager, this, _importProcessor, MainInfo().projectName); @@ -138,8 +140,6 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { // commandQueue.forEach(fileStructureStrategy.commandCreated); commandQueue.clear(); // await generateTrees(pb_project.forest, pb_project, context); - - await _commitDependencies(processInfo.genProjectPath); } void registerMiddleware(Middleware middleware) { @@ -154,8 +154,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { } ///Configure the required classes for the [PBGenerationConfiguration] - Future setUpConfiguration( - PBProject pbProject) async { + Future setUpConfiguration(PBProject pbProject) async { fileStructureStrategy = FlutterFileStructureStrategy( pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); commandObservers.add(fileStructureStrategy); @@ -164,10 +163,12 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { await fileStructureStrategy.setUpDirectories(); } - Future _commitDependencies(String projectPath) async { + Future _commitDependencies( + String projectPath, PBProject project) async { var writer = pageWriter; if (writer is PBFlutterWriter) { - writer.submitDependencies(p.join(projectPath, 'pubspec.yaml')); + writer.submitDependencies(p.join(projectPath, 'pubspec.yaml'), + project.genProjectData.dependencies); } } diff --git a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart index 3cbc53b9..b003c8b7 100644 --- a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/riverpod_middleware.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; @@ -16,7 +17,7 @@ class RiverpodGenerationConfiguration extends GenerationConfiguration { logger.info( 'Thanks for trying our state management configuration that is now in Beta!\nIf you run into any issues please feel free to post it in Github or in our Discord!'); fileStructureStrategy = RiverpodFileStructureStrategy( - pbProject.projectAbsPath, pageWriter, pbProject, fileSystemAnalyzer); + pbProject.projectAbsPath,pageWriter, pbProject, fileSystemAnalyzer); registerMiddleware(RiverpodMiddleware(generationManager, this)); logger.info('Setting up the directories'); await fileStructureStrategy.setUpDirectories(); diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index 4a64bc27..7d952080 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -11,11 +11,6 @@ class PBFlutterWriter implements PBPageWriter { factory PBFlutterWriter() => _instance; - @override - Map dependencies = {}; - @override - void addDependency(String packageName, String version) => - dependencies[packageName] = version; ///[fileAbsPath] should be the absolute path of the file @override @@ -80,7 +75,8 @@ class MyApp extends StatelessWidget { await mainFile.close(); } - void submitDependencies(String yamlAbsPath) async { + void submitDependencies( + String yamlAbsPath, Map dependencies) async { var line = 0; var readYaml = File(yamlAbsPath).readAsLinesSync(); if (dependencies.isNotEmpty) { @@ -101,11 +97,6 @@ class MyApp extends StatelessWidget { readYaml.insert(++line, ' assets:\n - assets/images/'); } } - var writeYaml = File(yamlAbsPath).openWrite(mode: FileMode.write); - - for (var i = 0; i < readYaml.length; ++i) { - writeYaml.writeln(readYaml[i]); - } - await writeYaml.flush(); + File(yamlAbsPath).writeAsStringSync(readYaml.join('\n')); } } diff --git a/lib/generation/generators/writers/pb_page_writer.dart b/lib/generation/generators/writers/pb_page_writer.dart index b424e1d5..a7c34aae 100644 --- a/lib/generation/generators/writers/pb_page_writer.dart +++ b/lib/generation/generators/writers/pb_page_writer.dart @@ -1,8 +1,5 @@ abstract class PBPageWriter { - Map dependencies = {}; void write(String code, String fileName); void append(String code, String fileName); - - void addDependency(String packageName, String version); } diff --git a/lib/generation/generators/writers/pb_traversal_adapter_writer.dart b/lib/generation/generators/writers/pb_traversal_adapter_writer.dart index 0a68eb43..cc55a1bb 100644 --- a/lib/generation/generators/writers/pb_traversal_adapter_writer.dart +++ b/lib/generation/generators/writers/pb_traversal_adapter_writer.dart @@ -6,10 +6,10 @@ import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart' /// The adapter's purpose is to disregard requests to modify any files, /// hence the empty return methods. class PBTraversalAdapterWriter extends PBPageWriter { - @override - void addDependency(String packageName, String version) { - return; - } + // @override + // void addDependency(String packageName, String version) { + // return; + // } @override void write(String code, String fileName) { From 5baf898b3ca3234e2e5bfa3311ef50d4e45a83ec Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 19 Aug 2021 11:20:59 -0500 Subject: [PATCH 320/404] Correctly generating `Appbar` Add case to TempChildrenStrategy for when we are adding multiple children --- lib/eggs/injected_app_bar.dart | 68 +++++++++++-------- .../visual-widgets/pb_bitmap_gen.dart | 5 +- .../entities/inherited_text.dart | 2 +- .../entities/layouts/stack.dart | 18 ++--- .../helpers/child_strategy.dart | 16 +++-- .../helpers/pb_intermediate_node_tree.dart | 19 +++--- .../pb_layout_generation_service.dart | 6 +- 7 files changed, 73 insertions(+), 61 deletions(-) diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 6a9a8c45..90daac68 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; @@ -14,6 +15,15 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; + /// String representing what the tag maps to + final LEADING_ATTR_NAME = 'leading'; + + /// String representing what the tag maps to + final MIDDLE_ATTR_NAME = 'title'; + + /// String representing what the tag maps to + final TRAILING_ATTR_NAME = 'actions'; + // PBIntermediateNode get leadingItem => getAttributeNamed('leading'); // PBIntermediateNode get middleItem => getAttributeNamed('title'); // PBIntermediateNode get trailingItem => getAttributeNamed('actions'); @@ -24,21 +34,20 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { String name, ) : super(UUID, frame, name) { generator = PBAppBarGenerator(); - alignStrategy = CustomAppBarAlignment(); + childrenStrategy = MultipleChildStrategy('children'); } @override String getAttributeNameOf(PBIntermediateNode node) { - if (node is PBInheritedIntermediate) { - // var attName = 'child'; + if (node is PBIntermediateNode) { if (node.name.contains('')) { - return 'leading'; + return LEADING_ATTR_NAME; } if (node.name.contains('')) { - return 'actions'; + return TRAILING_ATTR_NAME; } if (node.name.contains('')) { - return 'title'; + return MIDDLE_ATTR_NAME; } } @@ -54,13 +63,31 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { originalRef.name, ); - tree.childrenOf(appbar).forEach((element) { - element.attributeName = getAttributeNameOf(element); - }); + tree + .childrenOf(appbar) + .forEach((child) => child.attributeName = getAttributeNameOf(child)); return appbar; } + @override + void handleChildren(PBContext context) { + var children = context.tree.childrenOf(this); + + // Remove children that have an invalid `attributeName` + var validChildren = children.where(_isValidNode).toList(); + + context.tree.replaceChildrenOf(this, validChildren); + } + + /// Returns [true] if `node` has a valid `attributeName` in the eyes of the [InjectedAppbar]. + /// Returns [false] otherwise. + bool _isValidNode(PBIntermediateNode node) { + var validNames = [LEADING_ATTR_NAME, MIDDLE_ATTR_NAME, TRAILING_ATTR_NAME]; + + return validNames.any((name) => name == node.attributeName); + } + @override List layoutInstruction(List layer) { return layer; @@ -70,24 +97,6 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { void extractInformation(PBIntermediateNode incomingNode) {} } -class CustomAppBarAlignment extends AlignStrategy { - @override - void align(PBContext context, InjectedAppbar node) { - var middleItem = node.getAttributeNamed(context.tree, 'title'); - if (middleItem == null) { - return; - } - - /// This align only modifies middleItem - var tempNode = InjectedContainer( - middleItem.UUID, - middleItem.frame, - name: middleItem.name, - )..attributeName = 'title'; - context.tree.addEdges(tempNode, [middleItem]); - } -} - class PBAppBarGenerator extends PBGenerator { PBAppBarGenerator() : super(); @@ -99,11 +108,10 @@ class PBAppBarGenerator extends PBGenerator { buffer.write('AppBar('); - var children = - generatorContext.tree.edges(source).cast(); + var children = generatorContext.tree.childrenOf(source); children.forEach((child) { buffer.write( - '${child.attributeName}: ${_wrapOnBrackets(child.generator.generate(child, generatorContext), child == 'actions', child == 'leading')},'); + '${child.attributeName}: ${_wrapOnBrackets(child.generator.generate(child, generatorContext), child.attributeName == 'actions', child.attributeName == 'leading')},'); }); buffer.write(')'); diff --git a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart index efdcaa8e..39a64511 100644 --- a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart @@ -29,11 +29,12 @@ class PBBitmapGenerator extends PBGenerator { } var imagePath = source is InheritedBitmap - ? p.relative(source.referenceImage, from: MainInfo().genProjectPath) + // ? p.relative(source.referenceImage, from: MainInfo().genProjectPath) + ? 'assets/${source.referenceImage}' // Assuming PBDL will give us reference to image in the form of `image/.png` : ('assets/images/' + source.UUID + '.png'); buffer.write( '\'$imagePath\', ${_sizehelper.generate(source, generatorContext)})'); return buffer.toString(); } -} \ No newline at end of file +} diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 6a9557a1..7752aef3 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -113,7 +113,7 @@ class InheritedText extends PBVisualIntermediateNode // bottomRightCorner: inheritedText .frame.bottomRight, name: inheritedText.name, originalRef: json, - ); + )..attributeName = inheritedText.attributeName; tree.addEdges(container, [inheritedText]); // Return an [InheritedContainer] that wraps this text diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index bcc81ac6..0ab07edf 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:path/path.dart'; import 'package:uuid/uuid.dart'; ///Row contains nodes that are all `overlapping` to each other, without overlapping eachother @@ -32,13 +33,13 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { // @override // void resize(PBContext context) { - //FIXMEar depth = context.tree?.depthOf(this); + //FIXMEar depth = context.tree?.depthOf(this); - /// Since there are cases where [Stack] are being created, and - /// childrend are being populated, and consequently [Stack.resize] is being - /// called, then [depth] could be null. [depth] is null when the [PBIntermediateTree] - /// has not finished creating and converting PBDL nodes into [PBIntermediateNode]. - //FIXME if (depth != null && depth <= 1 && depth >= 0) { + /// Since there are cases where [Stack] are being created, and + /// childrend are being populated, and consequently [Stack.resize] is being + /// called, then [depth] could be null. [depth] is null when the [PBIntermediateTree] + /// has not finished creating and converting PBDL nodes into [PBIntermediateNode]. + //FIXME if (depth != null && depth <= 1 && depth >= 0) { //FIXME frame = context.canvasFrame; //FIXME } else { //FIXME super.resize(context); @@ -53,8 +54,9 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { children.forEach((element) => frame.boundingBox(element.frame)); var stack = PBIntermediateStackLayout(name: name)..frame = frame; - //FIXME stack.prototypeNode = prototypeNode; - //FIXME children.forEach((child) => stack.addChild(child)); + //FIXME stack.prototypeNode = prototypeNode; + //FIXME children.forEach((child) => stack.addChild(child)); + currentContext.tree.addEdges(stack, children); return stack; } diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index e520f1e7..61f6d6ed 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:quick_log/quick_log.dart'; @@ -110,7 +111,7 @@ class TempChildrenStrategy extends ChildrenStrategy { ChildrenMod addChild, tree) { var targetChildren = tree.childrenOf(target); var group = targetChildren.firstWhere( - (element) => element is TempGroupLayoutNode, + (element) => element is PBLayoutIntermediateNode, orElse: () => null); children = children is List ? children : [children]; @@ -122,15 +123,18 @@ class TempChildrenStrategy extends ChildrenStrategy { } /// Have no TempGroupLayoutNode but `target` already has children - else if (targetChildren.isNotEmpty) { + /// we are adding multiple children to an empty `target` + else if (targetChildren.isNotEmpty || children.length > 1) { var temp = TempGroupLayoutNode(null, null, name: '${target.name}Group'); - addChild(temp, targetChildren); addChild(temp, children); - _resizeFrameBasedOn(targetChildren, temp); - _resizeFrameBasedOn(children, temp); + if (targetChildren.isNotEmpty) { + addChild(temp, targetChildren); + _resizeFrameBasedOn(targetChildren, temp); + tree.removeEdges(target); + } - tree.removeEdges(target); + _resizeFrameBasedOn(children, temp); addChild(target, [temp]); } // Adding a single child to empty `target` diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 50163680..6c4f5c9e 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -196,18 +196,17 @@ class PBIntermediateTree extends DirectedGraph { if (target.parent == null) { throw Error(); } + + // Create copy of children of `target` in order to not lose + // reference of them when removing `target` + var children = childrenOf(target); + + remove(target); + if (acceptChildren) { - /// In the eyes of the [PBIntermediateTree], two [PBIntermediateNodes] with the same [UUID] - /// are the same vertex, and thus have the same edges. Therefore we do not want to add more edges - /// pointing to the same children. We simply want to update the existing edges' pointers. - if (target.UUID == replacement.UUID) { - // Change pointers of `target`'s `children` to point to `replacement` - childrenOf(target).forEach((child) => child.parent = replacement); - } else { - addEdges(replacement, edges(target)); - } + addEdges(replacement, children); } - remove(target); + addEdges(target.parent, [replacement]); return true; } diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 58798852..6513cd91 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -111,9 +111,7 @@ class PBLayoutGenerationService extends AITHandler { /// Transforming the [TempGroupLayoutNode] into regular [PBLayoutIntermediateNode] void _transformGroup(PBIntermediateTree tree) { - tree - .whereType() - .forEach((tempGroup) { + tree.whereType().forEach((tempGroup) { tree.replaceNode( tempGroup, PBIntermediateStackLayout( @@ -160,7 +158,7 @@ class PBLayoutGenerationService extends AITHandler { ///of the generated layout. //FIXME tree.removeNode(currentNode, eliminateSubTree: true); //FIXME tree.removeNode(nextNode, eliminateSubTree: true); - tree.removeEdges(parent); + tree.removeEdges(parent, [currentNode, nextNode]); tree.addEdges(parent, [ layout.generateLayout([currentNode, nextNode], context, '${currentNode.name}${nextNode.name}${layout.runtimeType}') From 9cef5961e63b3894975af9b02ce6b880fd1c257e Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 19 Aug 2021 13:03:42 -0500 Subject: [PATCH 321/404] Add handling of `` elements to `actions` --- lib/eggs/injected_app_bar.dart | 35 +++++++++++++------ .../visual-widgets/pb_bitmap_gen.dart | 1 - .../entities/inherited_circle.g.dart | 2 ++ .../entities/inherited_oval.g.dart | 2 ++ .../entities/inherited_polygon.g.dart | 2 ++ .../entities/inherited_scaffold.g.dart | 2 ++ .../entities/inherited_shape_group.g.dart | 2 ++ .../entities/inherited_shape_path.g.dart | 2 ++ .../entities/inherited_star.g.dart | 2 ++ .../entities/injected_container.g.dart | 2 ++ .../layouts/temp_group_layout_node.g.dart | 2 ++ .../entities/pb_shared_instance.g.dart | 2 ++ .../entities/pb_shared_master_node.g.dart | 2 ++ 13 files changed, 46 insertions(+), 12 deletions(-) diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 90daac68..3a4f6dd0 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/injected_container import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -108,24 +109,36 @@ class PBAppBarGenerator extends PBGenerator { buffer.write('AppBar('); - var children = generatorContext.tree.childrenOf(source); - children.forEach((child) { + var actions = generatorContext.tree + .childrenOf(source) + .where((child) => child.attributeName == source.TRAILING_ATTR_NAME); + var children = generatorContext.tree + .childrenOf(source) + .where((child) => child.attributeName != source.TRAILING_ATTR_NAME); + + // [actions] require special handling due to being a list + if (actions.isNotEmpty) { buffer.write( - '${child.attributeName}: ${_wrapOnBrackets(child.generator.generate(child, generatorContext), child.attributeName == 'actions', child.attributeName == 'leading')},'); - }); + '${source.TRAILING_ATTR_NAME}: ${_getActions(actions, generatorContext)},'); + } + children.forEach((child) => buffer.write( + '${child.attributeName}: ${_wrapOnIconButton(child.generator.generate(child, generatorContext))},')); buffer.write(')'); return buffer.toString(); } } - String _wrapOnBrackets(String body, bool isActions, bool isLeading) { - if (isActions) { - return '[${_wrapOnIconButton(body)}]'; - } else if (isLeading) { - return _wrapOnIconButton(body); - } - return '$body'; + /// Returns list ot `actions` as individual [PBIntermediateNodes] + String _getActions(Iterable actions, PBContext context) { + var buffer = StringBuffer(); + + buffer.write('['); + actions.forEach((action) => buffer.write( + '${_wrapOnIconButton(action.generator.generate(action, context))},')); + buffer.write(']'); + + return buffer.toString(); } String _wrapOnIconButton(String body) { diff --git a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart index 39a64511..e5eb26d7 100644 --- a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart @@ -29,7 +29,6 @@ class PBBitmapGenerator extends PBGenerator { } var imagePath = source is InheritedBitmap - // ? p.relative(source.referenceImage, from: MainInfo().genProjectPath) ? 'assets/${source.referenceImage}' // Assuming PBDL will give us reference to image in the form of `image/.png` : ('assets/images/' + source.UUID + '.png'); diff --git a/lib/interpret_and_optimize/entities/inherited_circle.g.dart b/lib/interpret_and_optimize/entities/inherited_circle.g.dart index 23114e96..1e2e4ab3 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.g.dart @@ -15,6 +15,7 @@ InheritedCircle _$InheritedCircleFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -28,6 +29,7 @@ InheritedCircle _$InheritedCircleFromJson(Map json) { Map _$InheritedCircleToJson(InheritedCircle instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/inherited_oval.g.dart b/lib/interpret_and_optimize/entities/inherited_oval.g.dart index 0701a0ee..4d0fef92 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.g.dart @@ -15,6 +15,7 @@ InheritedOval _$InheritedOvalFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -28,6 +29,7 @@ InheritedOval _$InheritedOvalFromJson(Map json) { Map _$InheritedOvalToJson(InheritedOval instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart index 38ab83ae..18ba0409 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart @@ -15,6 +15,7 @@ InheritedPolygon _$InheritedPolygonFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -28,6 +29,7 @@ InheritedPolygon _$InheritedPolygonFromJson(Map json) { Map _$InheritedPolygonToJson(InheritedPolygon instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart index 09ca89d5..9ae4a709 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart @@ -17,6 +17,7 @@ InheritedScaffold _$InheritedScaffoldFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -30,6 +31,7 @@ InheritedScaffold _$InheritedScaffoldFromJson(Map json) { Map _$InheritedScaffoldToJson(InheritedScaffold instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart index 4d641982..00ef5e7c 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart @@ -15,6 +15,7 @@ InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -29,6 +30,7 @@ InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { Map _$InheritedShapeGroupToJson( InheritedShapeGroup instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart index df5c2758..2744a6e0 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart @@ -15,6 +15,7 @@ InheritedShapePath _$InheritedShapePathFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -28,6 +29,7 @@ InheritedShapePath _$InheritedShapePathFromJson(Map json) { Map _$InheritedShapePathToJson(InheritedShapePath instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/inherited_star.g.dart b/lib/interpret_and_optimize/entities/inherited_star.g.dart index 3087cb79..c42c2466 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.g.dart @@ -15,6 +15,7 @@ InheritedStar _$InheritedStarFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -28,6 +29,7 @@ InheritedStar _$InheritedStarFromJson(Map json) { Map _$InheritedStarToJson(InheritedStar instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/injected_container.g.dart b/lib/interpret_and_optimize/entities/injected_container.g.dart index f3eab2ee..843235fd 100644 --- a/lib/interpret_and_optimize/entities/injected_container.g.dart +++ b/lib/interpret_and_optimize/entities/injected_container.g.dart @@ -16,6 +16,7 @@ InjectedContainer _$InjectedContainerFromJson(Map json) { PrototypeNode.prototypeNodeFromJson(json['prototypeNode'] as String), type: json['type'] as String, ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -28,6 +29,7 @@ InjectedContainer _$InjectedContainerFromJson(Map json) { Map _$InjectedContainerToJson(InjectedContainer instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart index 200a0ed0..f588f77a 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart +++ b/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart @@ -19,6 +19,7 @@ TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { : PBIntermediateConstraints.fromJson( json['constraints'] as Map), ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -29,6 +30,7 @@ TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { Map _$TempGroupLayoutNodeToJson( TempGroupLayoutNode instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints?.toJson(), 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart index 6fc03f7b..eabff7bc 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart @@ -22,6 +22,7 @@ PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( json['prototypeNodeUUID'] as String), name: json['name'] as String, ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -36,6 +37,7 @@ PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( Map _$PBSharedInstanceIntermediateNodeToJson( PBSharedInstanceIntermediateNode instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints?.toJson(), 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart index bbf08daf..1b535f87 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart @@ -16,6 +16,7 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), ) + ..subsemantic = json['subsemantic'] as String ..constraints = json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -29,6 +30,7 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { Map _$PBSharedMasterNodeToJson(PBSharedMasterNode instance) => { + 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints?.toJson(), 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), From 9a62a34460235d53c557bf64b0739b8b84cde682 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 19 Aug 2021 15:57:12 -0600 Subject: [PATCH 322/404] WIP RENAMED TempGroupLayout to Group. This represents the start of the division of TempGroupLayout between Group/Frame. --- lib/controllers/interpret.dart | 2 +- lib/eggs/injected_tab.dart | 4 ++-- .../entities/alignments/injected_align.dart | 2 +- .../entities/inherited_circle.dart | 2 +- .../entities/inherited_container.dart | 2 +- .../entities/inherited_scaffold.dart | 4 ++-- .../entities/injected_container.dart | 2 +- .../layouts/exceptions/stack_exception.dart | 6 +++--- .../{temp_group_layout_node.dart => group.dart} | 11 +++++------ ...{temp_group_layout_node.g.dart => group.g.dart} | 10 ++++------ .../entities/pb_shared_master_node.dart | 2 +- .../abstract_intermediate_node_factory.dart | 4 ++-- .../helpers/child_strategy.dart | 6 +++--- .../services/pb_layout_generation_service.dart | 14 +++++++------- 14 files changed, 34 insertions(+), 37 deletions(-) rename lib/interpret_and_optimize/entities/layouts/{temp_group_layout_node.dart => group.dart} (88%) rename lib/interpret_and_optimize/entities/layouts/{temp_group_layout_node.g.dart => group.g.dart} (82%) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 9da548b1..f39c01ca 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -7,7 +7,7 @@ import 'dart:convert'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_aggregation_service.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index 07849ec7..c5241c73 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -45,7 +45,7 @@ class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { originalNode.name, prototypeNode: (originalNode as PBInheritedIntermediate).prototypeNode, ); - if (originalNode is! TempGroupLayoutNode) { + if (originalNode is! Group) { var designNode = _convertWrapper(originalNode); tree.addEdges(this, [designNode]); diff --git a/lib/interpret_and_optimize/entities/alignments/injected_align.dart b/lib/interpret_and_optimize/entities/alignments/injected_align.dart index 1fa972ec..bf7b42b0 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_align.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_align.dart @@ -2,7 +2,7 @@ import 'dart:math'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_align_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index c69f084a..1cbb5329 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/intermediate_border_info.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 0100bcae..e4c6f668 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 5c442346..65c9b362 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; @@ -63,7 +63,7 @@ class InheritedScaffold extends PBVisualIntermediateNode void handleChildren(PBContext context) { var children = getAllAtrributeNamed(context.tree, 'body'); // Top-most stack should have scaffold's frame to align children properly - var groupAtt = TempGroupLayoutNode(null, frame) + var groupAtt = Group(null, frame) ..name = '$name-Group' ..attributeName = 'body' ..parent = this; diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 12afae16..7e0cfa70 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart b/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart index e1d87092..f875aa69 100644 --- a/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart +++ b/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart @@ -1,7 +1,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/exceptions/layout_exception.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; @@ -16,7 +16,7 @@ class ColumnOverlappingException extends LayoutException incomingNode.frame.topLeft, currentNode.frame.bottomRight) && (currentNode is PBLayoutIntermediateNode && - currentNode is! TempGroupLayoutNode && + currentNode is! Group && currentNode is! PBIntermediateStackLayout)); } } @@ -31,7 +31,7 @@ class RowOverlappingException extends LayoutException with AxisComparisonRule { incomingNode.frame.topLeft, incomingNode.frame.bottomRight) && (currentNode is PBLayoutIntermediateNode && - currentNode is! TempGroupLayoutNode && + currentNode is! Group && currentNode is! PBIntermediateStackLayout)); } } diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart b/lib/interpret_and_optimize/entities/layouts/group.dart similarity index 88% rename from lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart rename to lib/interpret_and_optimize/entities/layouts/group.dart index 54715416..fd88dba2 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart +++ b/lib/interpret_and_optimize/entities/layouts/group.dart @@ -5,7 +5,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -13,12 +12,12 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; -part 'temp_group_layout_node.g.dart'; +part 'group.g.dart'; @JsonSerializable(ignoreUnannotated: true, explicitToJson: true) /// A temporary node that must be removed -class TempGroupLayoutNode extends PBLayoutIntermediateNode +class Group extends PBLayoutIntermediateNode implements PBInheritedIntermediate, IntermediateNodeFactory { @override @JsonKey( @@ -32,7 +31,7 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode @override Map originalRef; - TempGroupLayoutNode( + Group( String UUID, Rectangle frame, { this.originalRef, @@ -56,7 +55,7 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode } static PBIntermediateNode fromJson(Map json) { - var tempGroup = _$TempGroupLayoutNodeFromJson(json); + var tempGroup = _$GroupFromJson(json); // tempGroup.constraints = PBIntermediateConstraints.fromConstraints( // json['constraints'], tempGroup.frame.height, tempGroup.frame.width); return tempGroup; @@ -65,7 +64,7 @@ class TempGroupLayoutNode extends PBLayoutIntermediateNode @override PBIntermediateNode createIntermediateNode(Map json, PBIntermediateNode parent, PBIntermediateTree tree) => - (TempGroupLayoutNode.fromJson(json) as TempGroupLayoutNode) + (Group.fromJson(json) as Group) ..mapRawChildren(json, tree) ..originalRef = json; } diff --git a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart b/lib/interpret_and_optimize/entities/layouts/group.g.dart similarity index 82% rename from lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart rename to lib/interpret_and_optimize/entities/layouts/group.g.dart index f588f77a..2fae9759 100644 --- a/lib/interpret_and_optimize/entities/layouts/temp_group_layout_node.g.dart +++ b/lib/interpret_and_optimize/entities/layouts/group.g.dart @@ -1,13 +1,13 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'temp_group_layout_node.dart'; +part of 'group.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { - return TempGroupLayoutNode( +Group _$GroupFromJson(Map json) { + return Group( json['UUID'] as String, DeserializedRectangle.fromJson( json['boundaryRectangle'] as Map), @@ -27,9 +27,7 @@ TempGroupLayoutNode _$TempGroupLayoutNodeFromJson(Map json) { ..type = json['type'] as String; } -Map _$TempGroupLayoutNodeToJson( - TempGroupLayoutNode instance) => - { +Map _$GroupToJson(Group instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints?.toJson(), diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 63dff0b9..0dd5ef58 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -3,7 +3,7 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_mastersym_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index f95e26c4..005cc6e4 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_pa import 'package:parabeac_core/interpret_and_optimize/entities/inherited_star.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_triangle.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -35,7 +35,7 @@ class AbstractIntermediateNodeFactory { InheritedTriangle('$InheritedTriangle', null), PBSharedInstanceIntermediateNode('$PBSharedInstanceIntermediateNode', null), PBSharedMasterNode('$PBSharedMasterNode', null), - TempGroupLayoutNode('$TempGroupLayoutNode', null), + Group('$Group', null), }; AbstractIntermediateNodeFactory(); diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 61f6d6ed..369ee131 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -1,4 +1,4 @@ -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -104,7 +104,7 @@ class TempChildrenStrategy extends ChildrenStrategy { bool _containsSingleGroup( PBIntermediateNode group, List children) => - group is TempGroupLayoutNode && children.length == 1; + group is Group && children.length == 1; @override void addChild(PBIntermediateNode target, children, @@ -125,7 +125,7 @@ class TempChildrenStrategy extends ChildrenStrategy { /// Have no TempGroupLayoutNode but `target` already has children /// we are adding multiple children to an empty `target` else if (targetChildren.isNotEmpty || children.length > 1) { - var temp = TempGroupLayoutNode(null, null, name: '${target.name}Group'); + var temp = Group(null, null, name: '${target.name}Group'); addChild(temp, children); if (targetChildren.isNotEmpty) { diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 6513cd91..1000f669 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/cont import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; @@ -31,7 +31,7 @@ class PBLayoutGenerationService extends AITHandler { ContainerConstraintRule() ]; - ///Going to replace the [TempGroupLayoutNode]s by [PBLayoutIntermediateNode]s + ///Going to replace the [Group]s by [PBLayoutIntermediateNode]s ///The default [PBLayoutIntermediateNode] PBLayoutIntermediateNode _defaultLayout; @@ -84,15 +84,15 @@ class PBLayoutGenerationService extends AITHandler { } } - /// If this node is an unecessary [TempGroupLayoutNode], from the [tree] + /// If this node is an unecessary [Group], from the [tree] /// /// Ex: Designer put a group with one child that was a group /// and that group contained the visual nodes. void _removingMeaninglessGroup(PBIntermediateTree tree) { tree .where((node) => - node is TempGroupLayoutNode && tree.childrenOf(node).length <= 1) - .cast() + node is Group && tree.childrenOf(node).length <= 1) + .cast() .forEach((tempGroup) { var tempChildren = tree.childrenOf(tempGroup); tree.replaceNode( @@ -109,9 +109,9 @@ class PBLayoutGenerationService extends AITHandler { }); } - /// Transforming the [TempGroupLayoutNode] into regular [PBLayoutIntermediateNode] + /// Transforming the [Group] into regular [PBLayoutIntermediateNode] void _transformGroup(PBIntermediateTree tree) { - tree.whereType().forEach((tempGroup) { + tree.whereType().forEach((tempGroup) { tree.replaceNode( tempGroup, PBIntermediateStackLayout( From 0a5c97d18436293927f91c075b9869d53e46e8f6 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 19 Aug 2021 22:58:43 -0500 Subject: [PATCH 323/404] Enable prototyping generation Start tabbar support --- lib/controllers/interpret.dart | 2 +- lib/eggs/injected_tab.dart | 105 ------------------ lib/eggs/injected_tab_bar.dart | 49 ++++---- .../generators/layouts/pb_scaffold_gen.dart | 14 +-- .../symbols/pb_instancesym_gen.dart | 2 +- .../pb_prototype_aggregation_service.dart | 91 +++++++++------ .../pb_prototype_linker_service.dart | 22 ++-- .../entities/inherited_scaffold.dart | 2 +- .../helpers/pb_plugin_list_helper.dart | 13 --- 9 files changed, 98 insertions(+), 202 deletions(-) delete mode 100644 lib/eggs/injected_tab.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 9da548b1..13f13e68 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -66,6 +66,7 @@ class Interpret { return Future.value(node); }, index: 0, id: 'Indexing ${tree.name}'); + await _pbPrototypeLinkerService.linkPrototypeNodes(tree, context); // await PBPrototypeAggregationService().linkDanglingPrototypeNodes(); return aitServiceBuilder.build(tree: tree, context: context); @@ -138,7 +139,6 @@ class AITServiceBuilder { log.debug('Started running $name...'); try { if (transformation is AITNodeTransformation) { - for (var child in _intermediateTree) { var dVertex = await transformation(context, child, _intermediateTree); diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart deleted file mode 100644 index 07849ec7..00000000 --- a/lib/eggs/injected_tab.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:parabeac_core/generation/generators/pb_generator.dart'; -import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; -import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/temp_group_layout_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; - -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; - -class Tab extends PBEgg implements PBInjectedIntermediate, PrototypeEnable { - @override - PrototypeNode prototypeNode; - - Tab( - String UUID, - Rectangle frame, - String name, { - this.prototypeNode, - }) : super( - UUID, - frame, - name, - ) { - generator = PBTabGenerator(); - childrenStrategy = OneChildStrategy('child'); - } - - @override - String semanticName; - - @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode, - PBIntermediateTree tree) { - if (originalNode is PBInheritedIntermediate) { - var tab = Tab( - originalNode.UUID, - frame, - originalNode.name, - prototypeNode: (originalNode as PBInheritedIntermediate).prototypeNode, - ); - if (originalNode is! TempGroupLayoutNode) { - var designNode = _convertWrapper(originalNode); - - tree.addEdges(this, [designNode]); - } - return tab; - } - - return null; - } - - @override - List layoutInstruction(List layer) { - return layer; - } - - PBIntermediateNode _convertWrapper(PBIntermediateNode node) { - /// This is for plugins - var str = '${node.name}'; - node.name = str.replaceAll(RegExp(r'\<.*?\>'), ''); - - ///This is for symbol master - if (node is PBSharedMasterNode) { - /// Convert to AbstractGroup? - - } - - ///This is for symbol Instance - if (node is PBSharedInstanceIntermediateNode) {} - return node; - } - - @override - void extractInformation(PBIntermediateNode incomingNode) { - // TODO: implement extractInformation - } -} - -class PBTabGenerator extends PBGenerator { - PBTabGenerator() : super(); - - @override - String generate(PBIntermediateNode source, PBContext generatorContext) { - if (source is Tab) { - var buffer = StringBuffer(); - buffer.write('BottomNavigationBarItem('); - var child = - generatorContext.tree.edges(source).first as PBIntermediateNode; - buffer.write(child != null - ? 'icon: ${child.generator.generate(child, generatorContext)}' - : ''); - buffer.write(')'); - return buffer.toString(); - } else { - return ''; - } - } -} diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 97d6c688..393cb899 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -2,16 +2,14 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'dart:math'; -import 'injected_tab.dart'; - class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; @@ -27,47 +25,50 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { String name, ) : super(UUID, frame, name) { generator = PBTabBarGenerator(); + childrenStrategy = MultipleChildStrategy('children'); } @override String getAttributeNameOf(PBIntermediateNode node) { - if (node is PBInheritedIntermediate) { - if (node.name.contains('')) { - assert(node is! Tab, 'node should be a Tab'); - return 'tab'; - // node.attributeName = 'tab'; - // tree.addEdges(AITVertex(this), [AITVertex(node)]); - } - } - - if (node is Tab) { - return 'tab'; - // node.attributeName = 'tab'; - // tree.addEdges(AITVertex(this), [AITVertex(node)]); + if (node.name.contains('')) { + return 'tabs'; } return super.getAttributeNameOf(node); } @override - List layoutInstruction(List layer) {} + List layoutInstruction(List layer) { + return layer; + } + + @override + void extractInformation(PBIntermediateNode incomingNode) {} @override PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, PBIntermediateTree tree) { - var originalChildren = tree.childrenOf(originalRef); var tabbar = InjectedTabBar( originalRef.UUID, frame, originalRef.name, ); - tree.addEdges(tabbar, originalChildren); + + tree + .childrenOf(tabbar) + .forEach((child) => child.attributeName = getAttributeNameOf(child)); return tabbar; } @override - void extractInformation(PBIntermediateNode incomingNode) { - // TODO: implement extractInformation + void handleChildren(PBContext context) { + var children = context.tree.childrenOf(this); + + var validChildren = + children.where((child) => child.attributeName == 'tabs').toList(); + + // Ensure only nodes with `tab` remain + context.tree.replaceChildrenOf(this, validChildren); } } @@ -86,11 +87,9 @@ class PBTabBarGenerator extends PBGenerator { buffer.write('type: BottomNavigationBarType.fixed,'); try { buffer.write('items:['); - for (var i = 0; i < tabs.length; i++) { - var tabChildren = context.tree.childrenOf(tabs[i]); + for (var tab in tabs) { buffer.write('BottomNavigationBarItem('); - var res = - context.generationManager.generate(tabChildren.first, context); + var res = context.generationManager.generate(tab, context); buffer.write('icon: $res,'); buffer.write('title: Text(""),'); buffer.write('),'); diff --git a/lib/generation/generators/layouts/pb_scaffold_gen.dart b/lib/generation/generators/layouts/pb_scaffold_gen.dart index 9c79c566..605ea442 100644 --- a/lib/generation/generators/layouts/pb_scaffold_gen.dart +++ b/lib/generation/generators/layouts/pb_scaffold_gen.dart @@ -32,13 +32,13 @@ class PBScaffoldGenerator extends PBGenerator { buffer.write('$appbarStr,\n'); } - if (bottomNavBar != null) { - buffer.write('bottomNavigationBar: '); - // generatorContext.sizingContext = SizingValueContext.PointValue; - var navigationBar = - bottomNavBar.generator.generate(bottomNavBar, context); - buffer.write('$navigationBar, \n'); - } + // if (bottomNavBar != null) { + // buffer.write('bottomNavigationBar: '); + // // generatorContext.sizingContext = SizingValueContext.PointValue; + // var navigationBar = + // bottomNavBar.generator.generate(bottomNavBar, context); + // buffer.write('$navigationBar, \n'); + // } if (body != null) { context.sizingContext = context.configuration.scaling diff --git a/lib/generation/generators/symbols/pb_instancesym_gen.dart b/lib/generation/generators/symbols/pb_instancesym_gen.dart index 2662ca00..81680f69 100644 --- a/lib/generation/generators/symbols/pb_instancesym_gen.dart +++ b/lib/generation/generators/symbols/pb_instancesym_gen.dart @@ -28,7 +28,7 @@ class PBSymbolInstanceGenerator extends PBGenerator { // recursively generate Symbol Instance constructors with overrides buffer.write(genSymbolInstance( - source.UUID, + source.SYMBOL_ID, source.sharedParamValues, generatorContext, )); diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index bd5f7628..5dffbbc3 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -1,4 +1,3 @@ -import 'package:parabeac_core/eggs/injected_tab.dart'; import 'package:parabeac_core/generation/prototyping/pb_dest_holder.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_storage.dart'; @@ -75,47 +74,65 @@ class PBPrototypeAggregationService { // TODO: refactor the structure if (iNode == null) { return iNode; - } else if (iNode is PBInheritedIntermediate) { - var destHolder = PBDestHolder( - iNode.UUID, + } else{ + var destHolder = PBDestHolder( + null, iNode.frame, (iNode as PBInheritedIntermediate).prototypeNode, ); - context.tree.addEdges(iNode); - //FIXME destHolder.addChild(iNode); + // Save parent pointer of `iNode` + destHolder.parent = iNode.parent; + context.tree.addEdges(destHolder, [iNode]); return destHolder; - } else if (iNode is PBLayoutIntermediateNode) { - var destHolder = PBDestHolder( - iNode.UUID, - iNode.frame, - iNode.prototypeNode, - ); - context.tree.addEdges(iNode); - //FIXME destHolder.addChild(iNode); - return destHolder; - } else if (iNode is InjectedContainer) { - var destHolder = PBDestHolder( - iNode.UUID, - iNode.frame, - iNode.prototypeNode, - ); - context.tree.addEdges(iNode); - //FIXME destHolder.addChild(iNode); - return destHolder; - } else if (iNode is Tab) { - var destHolder = PBDestHolder( - iNode.UUID, - iNode.frame, - iNode.prototypeNode, - ); - context.tree.childrenOf(iNode).forEach((element) { - context.tree.addEdges(element); - //FIXME destHolder.addChild(element); - }); - return destHolder; - } else { - return iNode; } + + // else if (iNode is PBInheritedIntermediate) { + // var destHolder = PBDestHolder( + // null, + // iNode.frame, + // (iNode as PBInheritedIntermediate).prototypeNode, + // ); + // // Save parent pointer of `iNode` + // destHolder.parent = iNode.parent; + // context.tree.addEdges(destHolder, [iNode]); + // //FIXME destHolder.addChild(iNode); + // return destHolder; + // } else if (iNode is PBLayoutIntermediateNode) { + // var destHolder = PBDestHolder( + // null, + // iNode.frame, + // iNode.prototypeNode, + // ); + // // Save parent pointer of `iNode` + // destHolder.parent = iNode.parent; + // context.tree.addEdges(destHolder, [iNode]); + // return destHolder; + // } else if (iNode is InjectedContainer) { + // var destHolder = PBDestHolder( + // null, + // iNode.frame, + // iNode.prototypeNode, + // ); + // // Save parent pointer of `iNode` + // destHolder.parent = iNode.parent; + // context.tree.addEdges(destHolder, [iNode]); + // return destHolder; + // } + // else if (iNode is Tab) { + // var destHolder = PBDestHolder( + // iNode.UUID, + // iNode.frame, + // iNode.prototypeNode, + // ); + // context.tree.childrenOf(iNode).forEach((element) { + // context.tree.addEdges(element); + // //FIXME destHolder.addChild(element); + // }); + // return destHolder; + // } + // else { + // return iNode; + // } } void iterateUnregisterNodes(PBIntermediateNode node) { diff --git a/lib/generation/prototyping/pb_prototype_linker_service.dart b/lib/generation/prototyping/pb_prototype_linker_service.dart index 290e0d55..9ae29bb1 100644 --- a/lib/generation/prototyping/pb_prototype_linker_service.dart +++ b/lib/generation/prototyping/pb_prototype_linker_service.dart @@ -24,26 +24,24 @@ class PBPrototypeLinkerService { } for (var element in tree) { if (element is InheritedScaffold) { - if (element is InheritedScaffold) { - await _prototypeStorage.addPageNode(element, context); - } else if (element is PrototypeEnable) { - if (((element)).prototypeNode?.destinationUUID != null && - (element).prototypeNode.destinationUUID.isNotEmpty) { - addAndPopulatePrototypeNode(element, rootNode, context); - } + await _prototypeStorage.addPageNode(element, context); + } else if (element is PrototypeEnable) { + if (((element)).prototypeNode?.destinationUUID != null && + (element).prototypeNode.destinationUUID.isNotEmpty) { + await addAndPopulatePrototypeNode(element, rootNode, context); } } } return rootNode; } - void addAndPopulatePrototypeNode( + Future addAndPopulatePrototypeNode( var currentNode, var rootNode, PBContext context) async { await _prototypeStorage.addPrototypeInstance(currentNode, context); - var pNode = - _aggregationService.populatePrototypeNode(context, currentNode); - if(pNode != null){ - context.tree.replaceNode(currentNode, pNode); + var pNode = _aggregationService.populatePrototypeNode(context, currentNode); + if (pNode != null) { + context.tree.addEdges(pNode.parent, [pNode]); + context.tree.removeEdges(pNode.parent, [currentNode]); } } } diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 5c442346..b3df46e1 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -54,7 +54,7 @@ class InheritedScaffold extends PBVisualIntermediateNode if (node is InjectedAppbar) { return 'appBar'; } else if (node is InjectedTabBar) { - return 'tabBar'; + return 'bottomNavigationBar'; } return super.getAttributeNameOf(node); } diff --git a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart index 7d359a62..1955506f 100644 --- a/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_plugin_list_helper.dart @@ -1,6 +1,5 @@ import 'package:parabeac_core/eggs/custom_egg.dart'; import 'package:parabeac_core/eggs/injected_app_bar.dart'; -import 'package:parabeac_core/eggs/injected_tab.dart'; import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -16,11 +15,6 @@ class PBPluginListHelper { allowListNames = { '': InjectedTabBar(null, null, ''), '': InjectedAppbar(null, null, ''), - '': Tab( - null, - null, - '', - ), '': CustomEgg(null, null, ''), }; } @@ -39,11 +33,6 @@ class PBPluginListHelper { null, '', ), - '': Tab( - null, - null, - '', - ), '': CustomEgg(null, null, ''), }; } @@ -55,7 +44,6 @@ class PBPluginListHelper { '', '', '', - '', '', ]; @@ -63,7 +51,6 @@ class PBPluginListHelper { '', '', '', - '', '', ]; From 5673fc9bc487b099ddb8d8a863a0ce69ab5a08ff Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 19 Aug 2021 21:58:44 -0600 Subject: [PATCH 324/404] WIP CREATED the Group classes to differenciate between Group & Frame. Furthermore, the normal groups are going to be removed in one of the interpret transformations. --- lib/controllers/interpret.dart | 12 +++-- lib/eggs/injected_tab.dart | 2 +- .../entities/alignments/injected_align.dart | 2 +- .../entities/inherited_circle.dart | 2 +- .../entities/inherited_container.dart | 2 +- .../entities/inherited_scaffold.dart | 5 ++- .../entities/injected_container.dart | 2 +- .../layouts/exceptions/stack_exception.dart | 2 +- .../entities/layouts/group/base_group.dart | 45 +++++++++++++++++++ .../{group.g.dart => group/base_group.g.dart} | 14 +++--- .../entities/layouts/group/frame_group.dart | 41 +++++++++++++++++ .../entities/layouts/group/frame_group.g.dart | 40 +++++++++++++++++ .../entities/layouts/{ => group}/group.dart | 24 ++++------ .../entities/pb_shared_master_node.dart | 2 +- .../abstract_intermediate_node_factory.dart | 7 ++- .../helpers/child_strategy.dart | 5 ++- .../helpers/pb_intermediate_node_tree.dart | 12 +++++ .../pb_layout_generation_service.dart | 2 +- 18 files changed, 181 insertions(+), 40 deletions(-) create mode 100644 lib/interpret_and_optimize/entities/layouts/group/base_group.dart rename lib/interpret_and_optimize/entities/layouts/{group.g.dart => group/base_group.g.dart} (77%) create mode 100644 lib/interpret_and_optimize/entities/layouts/group/frame_group.dart create mode 100644 lib/interpret_and_optimize/entities/layouts/group/frame_group.g.dart rename lib/interpret_and_optimize/entities/layouts/{ => group}/group.dart (74%) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index f39c01ca..2e58b39c 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -7,7 +7,8 @@ import 'dart:convert'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_aggregation_service.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/base_group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; @@ -64,7 +65,13 @@ class Interpret { elementStorage.treeUUIDs[tree.UUID] = tree; elementStorage.elementToTree[node.UUID] = tree.UUID; return Future.value(node); - }, index: 0, id: 'Indexing ${tree.name}'); + }, index: 0, id: 'Indexing ${tree.name}').addTransformation( + (PBContext context, PBIntermediateTree tree) { + tree + .whereType() + .forEach((node) => tree.remove(node, keepChildren: true)); + return Future.value(tree); + }, index: 1, id: 'Removing the $BaseGroup from ${tree.name}'); // await PBPrototypeAggregationService().linkDanglingPrototypeNodes(); @@ -138,7 +145,6 @@ class AITServiceBuilder { log.debug('Started running $name...'); try { if (transformation is AITNodeTransformation) { - for (var child in _intermediateTree) { var dVertex = await transformation(context, child, _intermediateTree); diff --git a/lib/eggs/injected_tab.dart b/lib/eggs/injected_tab.dart index c5241c73..6da43288 100644 --- a/lib/eggs/injected_tab.dart +++ b/lib/eggs/injected_tab.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inhe import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/entities/alignments/injected_align.dart b/lib/interpret_and_optimize/entities/alignments/injected_align.dart index bf7b42b0..bb4f9531 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_align.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_align.dart @@ -2,7 +2,7 @@ import 'dart:math'; import 'package:parabeac_core/generation/generators/visual-widgets/pb_align_gen.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 1cbb5329..c267af97 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/generation/generators/visual-widgets/pb_bitmap_gen import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/intermediate_border_info.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index e4c6f668..d03370c1 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 65c9b362..560c345b 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -4,7 +4,8 @@ import 'package:parabeac_core/eggs/injected_tab_bar.dart'; import 'package:parabeac_core/generation/generators/layouts/pb_scaffold_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/frame_group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; @@ -63,7 +64,7 @@ class InheritedScaffold extends PBVisualIntermediateNode void handleChildren(PBContext context) { var children = getAllAtrributeNamed(context.tree, 'body'); // Top-most stack should have scaffold's frame to align children properly - var groupAtt = Group(null, frame) + var groupAtt = FrameGroup(null, frame) ..name = '$name-Group' ..attributeName = 'body' ..parent = this; diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 7e0cfa70..7d8f8c26 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -4,7 +4,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_prototype_enabled.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart b/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart index f875aa69..5174e010 100644 --- a/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart +++ b/lib/interpret_and_optimize/entities/layouts/exceptions/stack_exception.dart @@ -1,7 +1,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/exceptions/layout_exception.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/axis_comparison_rules.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/entities/layouts/group/base_group.dart b/lib/interpret_and_optimize/entities/layouts/group/base_group.dart new file mode 100644 index 00000000..573935b5 --- /dev/null +++ b/lib/interpret_and_optimize/entities/layouts/group/base_group.dart @@ -0,0 +1,45 @@ +import 'dart:math'; + +import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; + +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; + +import 'group.dart'; + +part 'base_group.g.dart'; + +@JsonSerializable(ignoreUnannotated: true, createToJson: true) + +/// A temporary node that must be removed +class BaseGroup extends Group + implements PBInheritedIntermediate, IntermediateNodeFactory { + BaseGroup( + String UUID, + Rectangle frame, { + Map originalRef, + String name, + PrototypeNode prototypeNode, + PBIntermediateConstraints constraints, + }) : super( + UUID, + frame, + name: name, + prototypeNode: prototypeNode, + originalRef: originalRef, + ); + + @override + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => + _$BaseGroupFromJson(json) + ..mapRawChildren(json, tree) + ..originalRef = json; +} diff --git a/lib/interpret_and_optimize/entities/layouts/group.g.dart b/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart similarity index 77% rename from lib/interpret_and_optimize/entities/layouts/group.g.dart rename to lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart index 2fae9759..eda9846a 100644 --- a/lib/interpret_and_optimize/entities/layouts/group.g.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart @@ -1,13 +1,13 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'group.dart'; +part of 'base_group.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -Group _$GroupFromJson(Map json) { - return Group( +BaseGroup _$BaseGroupFromJson(Map json) { + return BaseGroup( json['UUID'] as String, DeserializedRectangle.fromJson( json['boundaryRectangle'] as Map), @@ -27,13 +27,13 @@ Group _$GroupFromJson(Map json) { ..type = json['type'] as String; } -Map _$GroupToJson(Group instance) => { +Map _$BaseGroupToJson(BaseGroup instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, - 'constraints': instance.constraints?.toJson(), + 'constraints': instance.constraints, 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), - 'style': instance.auxiliaryData?.toJson(), + 'style': instance.auxiliaryData, 'name': instance.name, - 'prototypeNodeUUID': instance.prototypeNode?.toJson(), + 'prototypeNodeUUID': instance.prototypeNode, 'type': instance.type, }; diff --git a/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart new file mode 100644 index 00000000..6a1e8abd --- /dev/null +++ b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart @@ -0,0 +1,41 @@ +import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/exceptions/layout_exception.dart'; +import 'dart:math'; + +import 'package:json_annotation/json_annotation.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; + +part 'frame_group.g.dart'; + +@JsonSerializable(ignoreUnannotated: true, createToJson: true) + +/// When creating [FrameGroup]s that is not from JSON (In other words, its being injected rather than inherited) +/// the values for the [PBIntermediateConstraints] are going to be [PBIntermediateConstraints.defaultConstraints()]. +/// Furthermore, the [frame] is going to be as big as it could be if the [FrameGroup] was injected rather than derived +/// from the JSON file. +class FrameGroup extends Group { + @override + @JsonKey() + String type = 'frame'; + + FrameGroup(String UUID, Rectangle frame, + {String name, + PrototypeNode prototypeNode, + PBIntermediateConstraints constraints}) + : super(UUID, frame, + name: name, prototypeNode: prototypeNode, constraints: constraints); + + @override + PBIntermediateNode createIntermediateNode(Map json, + PBIntermediateNode parent, PBIntermediateTree tree) => + _$FrameGroupFromJson(json) + ..mapRawChildren(json, tree) + ..originalRef = json; +} diff --git a/lib/interpret_and_optimize/entities/layouts/group/frame_group.g.dart b/lib/interpret_and_optimize/entities/layouts/group/frame_group.g.dart new file mode 100644 index 00000000..7de3451c --- /dev/null +++ b/lib/interpret_and_optimize/entities/layouts/group/frame_group.g.dart @@ -0,0 +1,40 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'frame_group.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +FrameGroup _$FrameGroupFromJson(Map json) { + return FrameGroup( + json['UUID'] as String, + DeserializedRectangle.fromJson( + json['boundaryRectangle'] as Map), + name: json['name'] as String, + prototypeNode: PrototypeNode.prototypeNodeFromJson( + json['prototypeNodeUUID'] as String), + constraints: json['constraints'] == null + ? null + : PBIntermediateConstraints.fromJson( + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String + ..auxiliaryData = json['style'] == null + ? null + : IntermediateAuxiliaryData.fromJson( + json['style'] as Map) + ..type = json['type'] as String; +} + +Map _$FrameGroupToJson(FrameGroup instance) => + { + 'subsemantic': instance.subsemantic, + 'UUID': instance.UUID, + 'constraints': instance.constraints, + 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'style': instance.auxiliaryData, + 'name': instance.name, + 'prototypeNodeUUID': instance.prototypeNode, + 'type': instance.type, + }; diff --git a/lib/interpret_and_optimize/entities/layouts/group.dart b/lib/interpret_and_optimize/entities/layouts/group/group.dart similarity index 74% rename from lib/interpret_and_optimize/entities/layouts/group.dart rename to lib/interpret_and_optimize/entities/layouts/group/group.dart index fd88dba2..c3f7bbf6 100644 --- a/lib/interpret_and_optimize/entities/layouts/group.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/group.dart @@ -12,12 +12,11 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; -part 'group.g.dart'; -@JsonSerializable(ignoreUnannotated: true, explicitToJson: true) +// @JsonSerializable(ignoreUnannotated: true, explicitToJson: true) /// A temporary node that must be removed -class Group extends PBLayoutIntermediateNode +abstract class Group extends PBLayoutIntermediateNode implements PBInheritedIntermediate, IntermediateNodeFactory { @override @JsonKey( @@ -54,17 +53,10 @@ class Group extends PBLayoutIntermediateNode return null; } - static PBIntermediateNode fromJson(Map json) { - var tempGroup = _$GroupFromJson(json); - // tempGroup.constraints = PBIntermediateConstraints.fromConstraints( - // json['constraints'], tempGroup.frame.height, tempGroup.frame.width); - return tempGroup; - } - - @override - PBIntermediateNode createIntermediateNode(Map json, - PBIntermediateNode parent, PBIntermediateTree tree) => - (Group.fromJson(json) as Group) - ..mapRawChildren(json, tree) - ..originalRef = json; + // @override + // PBIntermediateNode createIntermediateNode(Map json, + // PBIntermediateNode parent, PBIntermediateTree tree) => + // (Group.fromJson(json) as Group) + // ..mapRawChildren(json, tree) + // ..originalRef = json; } diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 0dd5ef58..ce207115 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -3,7 +3,7 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/symbols/pb_mastersym_gen.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index 005cc6e4..3c9db8db 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -10,7 +10,9 @@ import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_pa import 'package:parabeac_core/interpret_and_optimize/entities/inherited_star.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_text.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_triangle.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/base_group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/frame_group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -35,7 +37,8 @@ class AbstractIntermediateNodeFactory { InheritedTriangle('$InheritedTriangle', null), PBSharedInstanceIntermediateNode('$PBSharedInstanceIntermediateNode', null), PBSharedMasterNode('$PBSharedMasterNode', null), - Group('$Group', null), + BaseGroup('$Group', null), + FrameGroup('$FrameGroup', null), }; AbstractIntermediateNodeFactory(); diff --git a/lib/interpret_and_optimize/helpers/child_strategy.dart b/lib/interpret_and_optimize/helpers/child_strategy.dart index 369ee131..d37d234b 100644 --- a/lib/interpret_and_optimize/helpers/child_strategy.dart +++ b/lib/interpret_and_optimize/helpers/child_strategy.dart @@ -1,4 +1,5 @@ -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/frame_group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -125,7 +126,7 @@ class TempChildrenStrategy extends ChildrenStrategy { /// Have no TempGroupLayoutNode but `target` already has children /// we are adding multiple children to an empty `target` else if (targetChildren.isNotEmpty || children.length > 1) { - var temp = Group(null, null, name: '${target.name}Group'); + var temp = FrameGroup(null, null, name: '${target.name}Group'); addChild(temp, children); if (targetChildren.isNotEmpty) { diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 6c4f5c9e..afdb9719 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -172,6 +172,18 @@ class PBIntermediateTree extends DirectedGraph { super.removeEdges(parent, children); } + @override + + /// Essentially [super.remove()], however, if [keepChildren] is `true`, its going + /// to add the [edges(vertex)] into the [vertex.parent]; preventing the lost of the + /// [edges(vertex)]. + void remove(Vertex vertex, {bool keepChildren = false}) { + if (keepChildren && vertex is PBIntermediateNode) { + addEdges(vertex.parent, edges(vertex)); + } + super.remove(vertex); + } + /// Adding [PBIntermediateTree] as a dependecy. /// /// The [dependent] or its [dependent.rootNode] can not be `null` diff --git a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart index 1000f669..08c1b7e3 100644 --- a/lib/interpret_and_optimize/services/pb_layout_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_layout_generation_service.dart @@ -5,7 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/cont import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/stack_reduction_visual_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; From e6444a4ff3acc3a886d5465ccf30444c3985e988 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Fri, 20 Aug 2021 14:28:10 -0500 Subject: [PATCH 325/404] Add support for tag in appbar Tabbar is now being generated --- lib/eggs/injected_app_bar.dart | 71 ++++++++++--------- .../generators/layouts/pb_scaffold_gen.dart | 13 ++-- 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 3a4f6dd0..2001d504 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -1,11 +1,8 @@ +import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_inherited_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; @@ -17,17 +14,23 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { String semanticName = ''; /// String representing what the tag maps to - final LEADING_ATTR_NAME = 'leading'; + static final LEADING_ATTR_NAME = 'leading'; /// String representing what the tag maps to - final MIDDLE_ATTR_NAME = 'title'; + static final MIDDLE_ATTR_NAME = 'title'; - /// String representing what the tag maps to - final TRAILING_ATTR_NAME = 'actions'; + /// String representing what the tag maps to + static final TRAILING_ATTR_NAME = 'actions'; + + /// String representing what the tag maps to + static final BACKGROUND_ATTR_NAME = 'background'; - // PBIntermediateNode get leadingItem => getAttributeNamed('leading'); - // PBIntermediateNode get middleItem => getAttributeNamed('title'); - // PBIntermediateNode get trailingItem => getAttributeNamed('actions'); + final tagToName = { + '': LEADING_ATTR_NAME, + '': MIDDLE_ATTR_NAME, + '': TRAILING_ATTR_NAME, + '': BACKGROUND_ATTR_NAME + }; InjectedAppbar( String UUID, @@ -41,14 +44,12 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override String getAttributeNameOf(PBIntermediateNode node) { if (node is PBIntermediateNode) { - if (node.name.contains('')) { - return LEADING_ATTR_NAME; - } - if (node.name.contains('')) { - return TRAILING_ATTR_NAME; - } - if (node.name.contains('')) { - return MIDDLE_ATTR_NAME; + /// Iterate `keys` of [tagToName] to see if + /// any `key` matches [node.name] + for (var key in tagToName.keys) { + if (node.name.contains(key)) { + return tagToName[key]; + } } } @@ -83,11 +84,8 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { /// Returns [true] if `node` has a valid `attributeName` in the eyes of the [InjectedAppbar]. /// Returns [false] otherwise. - bool _isValidNode(PBIntermediateNode node) { - var validNames = [LEADING_ATTR_NAME, MIDDLE_ATTR_NAME, TRAILING_ATTR_NAME]; - - return validNames.any((name) => name == node.attributeName); - } + bool _isValidNode(PBIntermediateNode node) => + tagToName.values.any((name) => name == node.attributeName); @override List layoutInstruction(List layer) { @@ -109,17 +107,24 @@ class PBAppBarGenerator extends PBGenerator { buffer.write('AppBar('); - var actions = generatorContext.tree - .childrenOf(source) - .where((child) => child.attributeName == source.TRAILING_ATTR_NAME); - var children = generatorContext.tree - .childrenOf(source) - .where((child) => child.attributeName != source.TRAILING_ATTR_NAME); - - // [actions] require special handling due to being a list + // Get necessary attributes that need to be processed separately + var background = generatorContext.tree.childrenOf(source).firstWhere( + (child) => child.attributeName == InjectedAppbar.BACKGROUND_ATTR_NAME, + orElse: () => null); + var actions = generatorContext.tree.childrenOf(source).where( + (child) => child.attributeName == InjectedAppbar.TRAILING_ATTR_NAME); + var children = generatorContext.tree.childrenOf(source).where((child) => + child.attributeName != InjectedAppbar.TRAILING_ATTR_NAME && + child.attributeName != InjectedAppbar.BACKGROUND_ATTR_NAME); + + if (background != null) { + // TODO: PBColorGen may need a refactor in order to support `backgroundColor` when inside this tag + buffer.write( + 'backgroundColor: Color(${background.auxiliaryData?.color?.toString()}),'); + } if (actions.isNotEmpty) { buffer.write( - '${source.TRAILING_ATTR_NAME}: ${_getActions(actions, generatorContext)},'); + '${InjectedAppbar.TRAILING_ATTR_NAME}: ${_getActions(actions, generatorContext)},'); } children.forEach((child) => buffer.write( '${child.attributeName}: ${_wrapOnIconButton(child.generator.generate(child, generatorContext))},')); diff --git a/lib/generation/generators/layouts/pb_scaffold_gen.dart b/lib/generation/generators/layouts/pb_scaffold_gen.dart index 605ea442..941a8455 100644 --- a/lib/generation/generators/layouts/pb_scaffold_gen.dart +++ b/lib/generation/generators/layouts/pb_scaffold_gen.dart @@ -32,13 +32,12 @@ class PBScaffoldGenerator extends PBGenerator { buffer.write('$appbarStr,\n'); } - // if (bottomNavBar != null) { - // buffer.write('bottomNavigationBar: '); - // // generatorContext.sizingContext = SizingValueContext.PointValue; - // var navigationBar = - // bottomNavBar.generator.generate(bottomNavBar, context); - // buffer.write('$navigationBar, \n'); - // } + if (bottomNavBar != null) { + buffer.write('bottomNavigationBar: '); + var navigationBar = + bottomNavBar.generator.generate(bottomNavBar, context); + buffer.write('$navigationBar, \n'); + } if (body != null) { context.sizingContext = context.configuration.scaling From 61c44d35aaae7a8c610713d00c6fb9295f4398e4 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Fri, 20 Aug 2021 16:38:02 -0500 Subject: [PATCH 326/404] Added support for tabbar and background --- lib/eggs/injected_tab_bar.dart | 36 ++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 393cb899..94fdebb7 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -14,7 +14,13 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override String semanticName = ''; - // List get tabs => getAllAtrributeNamed('tabs'); + static final TAB_ATTR_NAME = 'tabs'; + static final BACKGROUND_ATTR_NAME = 'background'; + + final nameToAttr = { + '': TAB_ATTR_NAME, + '': BACKGROUND_ATTR_NAME, + }; @override AlignStrategy alignStrategy = NoAlignment(); @@ -30,9 +36,13 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override String getAttributeNameOf(PBIntermediateNode node) { - if (node.name.contains('')) { - return 'tabs'; + var matchingKey = nameToAttr.keys + .firstWhere((key) => node.name.contains(key), orElse: () => null); + + if (matchingKey != null) { + return nameToAttr[matchingKey]; } + return super.getAttributeNameOf(node); } @@ -64,8 +74,11 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { void handleChildren(PBContext context) { var children = context.tree.childrenOf(this); - var validChildren = - children.where((child) => child.attributeName == 'tabs').toList(); + var validChildren = children + .where((child) => + child.attributeName == TAB_ATTR_NAME || + child.attributeName == BACKGROUND_ATTR_NAME) + .toList(); // Ensure only nodes with `tab` remain context.tree.replaceChildrenOf(this, validChildren); @@ -80,10 +93,21 @@ class PBTabBarGenerator extends PBGenerator { // generatorContext.sizingContext = SizingValueContext.PointValue; if (source is InjectedTabBar) { // var tabs = source.tabs; - var tabs = source.getAllAtrributeNamed(context.tree, 'tabs'); + var tabs = source.getAllAtrributeNamed( + context.tree, InjectedTabBar.TAB_ATTR_NAME); + var background = context.tree.childrenOf(source).firstWhere( + (child) => child.attributeName == InjectedTabBar.BACKGROUND_ATTR_NAME, + orElse: () => null); var buffer = StringBuffer(); buffer.write('BottomNavigationBar('); + + if (background != null) { + // TODO: PBColorGen may need a refactor in order to support `backgroundColor` when inside this tag + buffer.write( + 'backgroundColor: Color(${background.auxiliaryData?.color?.toString()}),'); + } + buffer.write('type: BottomNavigationBarType.fixed,'); try { buffer.write('items:['); From 3b66e5ccf062727385d16b9fc467ade24b5c1b08 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Fri, 20 Aug 2021 19:04:56 -0600 Subject: [PATCH 327/404] WIP z-axis sorting for (particularly important for Stack) - Added Rectangle3D that just contains z-axis. - Added custom sorting for Stack. - Deleted unused code. --- lib/eggs/custom_egg.dart | 4 +- lib/eggs/injected_app_bar.dart | 4 +- lib/eggs/injected_back_arrow.dart | 4 +- lib/eggs/injected_tab_bar.dart | 4 +- .../generators/plugins/pb_plugin_node.dart | 4 +- .../visual-widgets/pb_positioned_gen.dart | 4 - .../prototyping/pb_dest_holder.dart | 2 +- .../entities/alignments/flexible.dart | 2 +- .../entities/alignments/injected_align.dart | 2 +- .../alignments/injected_positioned.dart | 2 +- .../entities/alignments/padding.dart | 2 +- .../entities/alignments/spacer.dart | 2 +- .../entities/inherited_bitmap.dart | 2 +- .../entities/inherited_bitmap.g.dart | 5 +- .../entities/inherited_circle.dart | 2 +- .../entities/inherited_circle.g.dart | 5 +- .../entities/inherited_container.dart | 4 +- .../entities/inherited_container.g.dart | 5 +- .../entities/inherited_oval.dart | 2 +- .../entities/inherited_oval.g.dart | 5 +- .../entities/inherited_polygon.dart | 2 +- .../entities/inherited_polygon.g.dart | 5 +- .../entities/inherited_scaffold.dart | 4 +- .../entities/inherited_scaffold.g.dart | 5 +- .../entities/inherited_shape_group.dart | 2 +- .../entities/inherited_shape_group.g.dart | 5 +- .../entities/inherited_shape_path.dart | 2 +- .../entities/inherited_shape_path.g.dart | 5 +- .../entities/inherited_star.dart | 2 +- .../entities/inherited_star.g.dart | 5 +- .../entities/inherited_text.dart | 2 +- .../entities/inherited_text.g.dart | 5 +- .../entities/inherited_triangle.dart | 2 +- .../entities/inherited_triangle.g.dart | 5 +- .../entities/injected_container.dart | 2 +- .../entities/injected_container.g.dart | 5 +- .../entities/layouts/column.dart | 2 +- .../entities/layouts/group/base_group.dart | 2 +- .../entities/layouts/group/base_group.g.dart | 5 +- .../entities/layouts/group/frame_group.dart | 2 +- .../entities/layouts/group/frame_group.g.dart | 5 +- .../entities/layouts/group/group.dart | 2 +- .../entities/layouts/stack.dart | 5 + .../entities/pb_deny_list_node.dart | 2 +- .../entities/pb_shared_instance.dart | 2 +- .../entities/pb_shared_instance.g.dart | 5 +- .../entities/pb_shared_master_node.dart | 2 +- .../entities/pb_shared_master_node.g.dart | 5 +- .../subclasses/pb_intermediate_node.dart | 103 ++++++++---------- .../subclasses/pb_intermediate_node.g.dart | 2 +- .../pb_layout_intermediate_node.dart | 73 ++----------- .../pb_visual_intermediate_node.dart | 4 +- .../helpers/pb_context.dart | 11 +- .../helpers/pb_intermediate_dfs_iterator.dart | 31 ------ .../pb_intermediate_layer_iterator.dart | 32 ------ .../helpers/pb_intermediate_node_tree.dart | 40 +++---- lib/main.dart | 4 +- 57 files changed, 161 insertions(+), 302 deletions(-) delete mode 100644 lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart delete mode 100644 lib/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart diff --git a/lib/eggs/custom_egg.dart b/lib/eggs/custom_egg.dart index 9a5341e7..518f9057 100644 --- a/lib/eggs/custom_egg.dart +++ b/lib/eggs/custom_egg.dart @@ -19,7 +19,7 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { String semanticName = ''; CustomEgg( String UUID, - Rectangle frame, + Rectangle3D frame, String name, ) : super(UUID, frame, name) { generator = CustomEggGenerator(); @@ -32,7 +32,7 @@ class CustomEgg extends PBEgg implements PBInjectedIntermediate { } @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBEgg generatePluginNode(Rectangle3D frame, PBIntermediateNode originalRef, PBIntermediateTree tree) { return CustomEgg(originalRef.UUID, frame, originalRef.name.replaceAll('', '').pascalCase); diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 3a4f6dd0..c41098d0 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -31,7 +31,7 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { InjectedAppbar( String UUID, - Rectangle frame, + Rectangle3D frame, String name, ) : super(UUID, frame, name) { generator = PBAppBarGenerator(); @@ -56,7 +56,7 @@ class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { } @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBEgg generatePluginNode(Rectangle3D frame, PBIntermediateNode originalRef, PBIntermediateTree tree) { var appbar = InjectedAppbar( originalRef.UUID, diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart index 806d144d..a00179e6 100644 --- a/lib/eggs/injected_back_arrow.dart +++ b/lib/eggs/injected_back_arrow.dart @@ -21,7 +21,7 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { InjectedBackArrow( String UUID, - Rectangle frame, + Rectangle3D frame, String name, ) : super(UUID, frame, name) { generator = PBBackArrowGenerator(); @@ -31,7 +31,7 @@ class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { void extractInformation(PBIntermediateNode incomingNode) {} @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBEgg generatePluginNode(Rectangle3D frame, PBIntermediateNode originalRef, PBIntermediateTree tree) { return InjectedBackArrow( UUID, diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 393cb899..882eb232 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -21,7 +21,7 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { InjectedTabBar( String UUID, - Rectangle frame, + Rectangle3D frame, String name, ) : super(UUID, frame, name) { generator = PBTabBarGenerator(); @@ -45,7 +45,7 @@ class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { void extractInformation(PBIntermediateNode incomingNode) {} @override - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalRef, + PBEgg generatePluginNode(Rectangle3D frame, PBIntermediateNode originalRef, PBIntermediateTree tree) { var tabbar = InjectedTabBar( originalRef.UUID, diff --git a/lib/generation/generators/plugins/pb_plugin_node.dart b/lib/generation/generators/plugins/pb_plugin_node.dart index 682bffd6..52717e83 100644 --- a/lib/generation/generators/plugins/pb_plugin_node.dart +++ b/lib/generation/generators/plugins/pb_plugin_node.dart @@ -11,7 +11,7 @@ abstract class PBEgg extends PBVisualIntermediateNode { PBEgg( String UUID, - Rectangle frame, + Rectangle3D frame, String name, ) : super( UUID, @@ -24,7 +24,7 @@ abstract class PBEgg extends PBVisualIntermediateNode { List layoutInstruction(List layer) => layer; - PBEgg generatePluginNode(Rectangle frame, PBIntermediateNode originalNode, + PBEgg generatePluginNode(Rectangle3D frame, PBIntermediateNode originalNode, PBIntermediateTree tree); void extractInformation(PBIntermediateNode incomingNode); diff --git a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart index 8afffd1b..4deb11a6 100644 --- a/lib/generation/generators/visual-widgets/pb_positioned_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_positioned_gen.dart @@ -23,10 +23,6 @@ class PBPositionedGenerator extends PBGenerator { var buffer = StringBuffer('Positioned('); - // var boilerplate = _getBoilerplate(context.sizingContext); - // var xAxisBoilerplate = boilerplate.item1; - // var yAxisBoilerplate = boilerplate.item2; - /// Since the generation phase is going to run multiple times, we are going to have to /// create a copy/clone of the [PositionedValueHolder] instead of assigning the values /// directly to the [source.valueHolder]. This would causse the [source.valueHolder.getRatioPercentage] diff --git a/lib/generation/prototyping/pb_dest_holder.dart b/lib/generation/prototyping/pb_dest_holder.dart index c4c7a33e..f341d735 100644 --- a/lib/generation/prototyping/pb_dest_holder.dart +++ b/lib/generation/prototyping/pb_dest_holder.dart @@ -9,7 +9,7 @@ class PBDestHolder extends PBIntermediateNode { PrototypeNode pNode; PBDestHolder( - String UUID, Rectangle frame, this.pNode) + String UUID, Rectangle3D frame, this.pNode) : super(UUID, frame, '') { generator = PBPrototypeGenerator(pNode); childrenStrategy = OneChildStrategy('child'); diff --git a/lib/interpret_and_optimize/entities/alignments/flexible.dart b/lib/interpret_and_optimize/entities/alignments/flexible.dart index 62f9735d..c6d50f9a 100644 --- a/lib/interpret_and_optimize/entities/alignments/flexible.dart +++ b/lib/interpret_and_optimize/entities/alignments/flexible.dart @@ -14,7 +14,7 @@ class Flexible extends PBVisualIntermediateNode { //without breaking the json serializable Flexible( String UUID, - Rectangle frame, { + Rectangle3D frame, { // child, this.flex, }) : super( diff --git a/lib/interpret_and_optimize/entities/alignments/injected_align.dart b/lib/interpret_and_optimize/entities/alignments/injected_align.dart index bb4f9531..0bd587ae 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_align.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_align.dart @@ -13,7 +13,7 @@ class InjectedAlign extends PBVisualIntermediateNode double alignX; double alignY; - InjectedAlign(String UUID, Rectangle frame, String name) + InjectedAlign(String UUID, Rectangle3D frame, String name) : super(UUID, frame, name) { generator = PBAlignGenerator(); childrenStrategy = TempChildrenStrategy('child'); diff --git a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart index c0454898..a5a15774 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_positioned.dart @@ -15,7 +15,7 @@ class InjectedPositioned extends PBIntermediateNode InjectedPositioned( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.valueHolder, PBIntermediateConstraints constraints, }) : super(UUID, frame, '', constraints: constraints) { diff --git a/lib/interpret_and_optimize/entities/alignments/padding.dart b/lib/interpret_and_optimize/entities/alignments/padding.dart index 89351fbd..3b563d5b 100644 --- a/lib/interpret_and_optimize/entities/alignments/padding.dart +++ b/lib/interpret_and_optimize/entities/alignments/padding.dart @@ -16,7 +16,7 @@ class Padding extends PBVisualIntermediateNode { Padding( String UUID, - Rectangle frame, + Rectangle3D frame, this.childToParentConstraints, { this.left = 0, this.right = 0, diff --git a/lib/interpret_and_optimize/entities/alignments/spacer.dart b/lib/interpret_and_optimize/entities/alignments/spacer.dart index e0152bf3..9bac542a 100644 --- a/lib/interpret_and_optimize/entities/alignments/spacer.dart +++ b/lib/interpret_and_optimize/entities/alignments/spacer.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class Spacer extends PBVisualIntermediateNode { int flex; - Spacer(String UUID, Rectangle frame, {this.flex, PBContext currentContext}) + Spacer(String UUID, Rectangle3D frame, {this.flex, PBContext currentContext}) : super( UUID, frame, diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index 0fea39e9..4e3d186a 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -40,7 +40,7 @@ class InheritedBitmap extends PBVisualIntermediateNode @JsonKey(ignore: true) Map originalRef; - InheritedBitmap(String UUID, Rectangle frame, + InheritedBitmap(String UUID, Rectangle3D frame, {this.originalRef, String name, this.referenceImage, this.prototypeNode}) : super( UUID, diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart index b09cbd40..c9db6632 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart @@ -9,8 +9,7 @@ part of 'inherited_bitmap.dart'; InheritedBitmap _$InheritedBitmapFromJson(Map json) { return InheritedBitmap( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, referenceImage: json['imageReference'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( @@ -33,7 +32,7 @@ Map _$InheritedBitmapToJson(InheritedBitmap instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index c267af97..43d37bfe 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -35,7 +35,7 @@ class InheritedCircle extends PBVisualIntermediateNode InheritedCircle( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, String name, Point alignX, diff --git a/lib/interpret_and_optimize/entities/inherited_circle.g.dart b/lib/interpret_and_optimize/entities/inherited_circle.g.dart index 1e2e4ab3..2cb1d52e 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.g.dart @@ -9,8 +9,7 @@ part of 'inherited_circle.dart'; InheritedCircle _$InheritedCircleFromJson(Map json) { return InheritedCircle( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), @@ -32,7 +31,7 @@ Map _$InheritedCircleToJson(InheritedCircle instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index d03370c1..6a872a18 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -33,7 +33,7 @@ class InheritedContainer extends PBVisualIntermediateNode @override @JsonKey() - String type = 'rectangle'; + String type = 'Rectangle3D'; @override @JsonKey(ignore: true) @@ -41,7 +41,7 @@ class InheritedContainer extends PBVisualIntermediateNode InheritedContainer( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, String name, double alignX, diff --git a/lib/interpret_and_optimize/entities/inherited_container.g.dart b/lib/interpret_and_optimize/entities/inherited_container.g.dart index 98791fb7..5302d986 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.g.dart @@ -9,8 +9,7 @@ part of 'inherited_container.dart'; InheritedContainer _$InheritedContainerFromJson(Map json) { return InheritedContainer( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, isBackgroundVisible: json['isBackgroundVisible'] as bool ?? true, prototypeNode: PrototypeNode.prototypeNodeFromJson( @@ -33,7 +32,7 @@ Map _$InheritedContainerToJson(InheritedContainer instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index de0682c7..382a47d9 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -39,7 +39,7 @@ class InheritedOval extends PBVisualIntermediateNode InheritedOval( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, String name, Uint8List image, diff --git a/lib/interpret_and_optimize/entities/inherited_oval.g.dart b/lib/interpret_and_optimize/entities/inherited_oval.g.dart index 4d0fef92..559bf072 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.g.dart @@ -9,8 +9,7 @@ part of 'inherited_oval.dart'; InheritedOval _$InheritedOvalFromJson(Map json) { return InheritedOval( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), @@ -32,7 +31,7 @@ Map _$InheritedOvalToJson(InheritedOval instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index 314ce0b2..623a7f7a 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -40,7 +40,7 @@ class InheritedPolygon extends PBVisualIntermediateNode InheritedPolygon( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, name, Uint8List image, diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart index 18ba0409..6e1e3c4d 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart @@ -9,8 +9,7 @@ part of 'inherited_polygon.dart'; InheritedPolygon _$InheritedPolygonFromJson(Map json) { return InheritedPolygon( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'], prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), @@ -32,7 +31,7 @@ Map _$InheritedPolygonToJson(InheritedPolygon instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 0f203a70..f366ff98 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -43,7 +43,7 @@ class InheritedScaffold extends PBVisualIntermediateNode Map originalRef; InheritedScaffold( - String UUID, Rectangle frame, String name, this.originalRef, + String UUID, Rectangle3D frame, String name, this.originalRef, {this.isHomeScreen, this.prototypeNode}) : super(UUID, frame, name) { generator = PBScaffoldGenerator(); @@ -106,7 +106,7 @@ class InheritedScaffold extends PBVisualIntermediateNode // InheritedScaffold( // String UUID, -// Rectangle frame, { +// Rectangle3D frame, { // this.originalRef, // String name, // this.isHomeScreen, diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart index 9ae4a709..69885423 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart @@ -9,8 +9,7 @@ part of 'inherited_scaffold.dart'; InheritedScaffold _$InheritedScaffoldFromJson(Map json) { return InheritedScaffold( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), json['name'] as String, json['originalRef'] as Map, isHomeScreen: json['isFlowHome'] as bool ?? false, @@ -34,7 +33,7 @@ Map _$InheritedScaffoldToJson(InheritedScaffold instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index 63170195..ea8227cb 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -39,7 +39,7 @@ class InheritedShapeGroup extends PBVisualIntermediateNode InheritedShapeGroup( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, String name, Uint8List image, diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart index 00ef5e7c..3aa17d4d 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart @@ -9,8 +9,7 @@ part of 'inherited_shape_group.dart'; InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { return InheritedShapeGroup( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), @@ -33,7 +32,7 @@ Map _$InheritedShapeGroupToJson( 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 60686716..6d3b7386 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -41,7 +41,7 @@ class InheritedShapePath extends PBVisualIntermediateNode InheritedShapePath( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, String name, Uint8List image, diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart index 2744a6e0..3d048b65 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart @@ -9,8 +9,7 @@ part of 'inherited_shape_path.dart'; InheritedShapePath _$InheritedShapePathFromJson(Map json) { return InheritedShapePath( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), @@ -32,7 +31,7 @@ Map _$InheritedShapePathToJson(InheritedShapePath instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index a1edc621..5f63b8ee 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -41,7 +41,7 @@ class InheritedStar extends PBVisualIntermediateNode InheritedStar( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, name, Uint8List image, diff --git a/lib/interpret_and_optimize/entities/inherited_star.g.dart b/lib/interpret_and_optimize/entities/inherited_star.g.dart index c42c2466..777f273b 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.g.dart @@ -9,8 +9,7 @@ part of 'inherited_star.dart'; InheritedStar _$InheritedStarFromJson(Map json) { return InheritedStar( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'], prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), @@ -32,7 +31,7 @@ Map _$InheritedStarToJson(InheritedStar instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index 7752aef3..ceaeb152 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -60,7 +60,7 @@ class InheritedText extends PBVisualIntermediateNode InheritedText( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, name, this.alignmenttype, diff --git a/lib/interpret_and_optimize/entities/inherited_text.g.dart b/lib/interpret_and_optimize/entities/inherited_text.g.dart index ea119993..f0f057df 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.g.dart @@ -9,8 +9,7 @@ part of 'inherited_text.dart'; InheritedText _$InheritedTextFromJson(Map json) { return InheritedText( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'], isTextParameter: json['isTextParameter'] as bool ?? false, prototypeNode: PrototypeNode.prototypeNodeFromJson( @@ -34,7 +33,7 @@ Map _$InheritedTextToJson(InheritedText instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'isTextParameter': instance.isTextParameter, diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 1dbf0133..2c5b506f 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -40,7 +40,7 @@ class InheritedTriangle extends PBVisualIntermediateNode InheritedTriangle( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, String name, Uint8List image, diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart index 8d869097..9408fe7c 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart @@ -9,8 +9,7 @@ part of 'inherited_triangle.dart'; InheritedTriangle _$InheritedTriangleFromJson(Map json) { return InheritedTriangle( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), @@ -32,7 +31,7 @@ Map _$InheritedTriangleToJson(InheritedTriangle instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 7d8f8c26..802adfb1 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -36,7 +36,7 @@ class InjectedContainer extends PBVisualIntermediateNode InjectedContainer( UUID, - Rectangle frame, { + Rectangle3D frame, { String name, double alignX, double alignY, diff --git a/lib/interpret_and_optimize/entities/injected_container.g.dart b/lib/interpret_and_optimize/entities/injected_container.g.dart index 843235fd..edc85e40 100644 --- a/lib/interpret_and_optimize/entities/injected_container.g.dart +++ b/lib/interpret_and_optimize/entities/injected_container.g.dart @@ -9,8 +9,7 @@ part of 'injected_container.dart'; InjectedContainer _$InjectedContainerFromJson(Map json) { return InjectedContainer( json['UUID'], - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson(json['prototypeNode'] as String), @@ -32,7 +31,7 @@ Map _$InjectedContainerToJson(InjectedContainer instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNode': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/layouts/column.dart b/lib/interpret_and_optimize/entities/layouts/column.dart index 5183f7b1..b8d5860f 100644 --- a/lib/interpret_and_optimize/entities/layouts/column.dart +++ b/lib/interpret_and_optimize/entities/layouts/column.dart @@ -30,7 +30,7 @@ class PBIntermediateColumnLayout extends PBLayoutIntermediateNode { @override AlignStrategy alignStrategy = ColumnAlignment(); - PBIntermediateColumnLayout(Rectangle frame, {String name}) + PBIntermediateColumnLayout(Rectangle3D frame, {String name}) : super(null, frame, COLUMN_RULES, COLUMN_EXCEPTIONS, name) { generator = PBColumnGenerator(); } diff --git a/lib/interpret_and_optimize/entities/layouts/group/base_group.dart b/lib/interpret_and_optimize/entities/layouts/group/base_group.dart index 573935b5..816fc736 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/base_group.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/base_group.dart @@ -23,7 +23,7 @@ class BaseGroup extends Group implements PBInheritedIntermediate, IntermediateNodeFactory { BaseGroup( String UUID, - Rectangle frame, { + Rectangle3D frame, { Map originalRef, String name, PrototypeNode prototypeNode, diff --git a/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart b/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart index eda9846a..ce884743 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart @@ -9,8 +9,7 @@ part of 'base_group.dart'; BaseGroup _$BaseGroupFromJson(Map json) { return BaseGroup( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), @@ -31,7 +30,7 @@ Map _$BaseGroupToJson(BaseGroup instance) => { 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart index 6a1e8abd..86a97be3 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart @@ -25,7 +25,7 @@ class FrameGroup extends Group { @JsonKey() String type = 'frame'; - FrameGroup(String UUID, Rectangle frame, + FrameGroup(String UUID, Rectangle3D frame, {String name, PrototypeNode prototypeNode, PBIntermediateConstraints constraints}) diff --git a/lib/interpret_and_optimize/entities/layouts/group/frame_group.g.dart b/lib/interpret_and_optimize/entities/layouts/group/frame_group.g.dart index 7de3451c..af5a6bb5 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/frame_group.g.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/frame_group.g.dart @@ -9,8 +9,7 @@ part of 'frame_group.dart'; FrameGroup _$FrameGroupFromJson(Map json) { return FrameGroup( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), @@ -32,7 +31,7 @@ Map _$FrameGroupToJson(FrameGroup instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData, 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/layouts/group/group.dart b/lib/interpret_and_optimize/entities/layouts/group/group.dart index c3f7bbf6..4dd65ff1 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/group.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/group.dart @@ -32,7 +32,7 @@ abstract class Group extends PBLayoutIntermediateNode Group( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, String name, this.prototypeNode, diff --git a/lib/interpret_and_optimize/entities/layouts/stack.dart b/lib/interpret_and_optimize/entities/layouts/stack.dart index 0ab07edf..d63e364a 100644 --- a/lib/interpret_and_optimize/entities/layouts/stack.dart +++ b/lib/interpret_and_optimize/entities/layouts/stack.dart @@ -46,6 +46,11 @@ class PBIntermediateStackLayout extends PBLayoutIntermediateNode { //FIXME } // } + @override + void sortChildren(List children) => + children.sort((c0, c1) => c0.frame.z.compareTo(c1.frame.z)); + + @override PBLayoutIntermediateNode generateLayout(List children, PBContext currentContext, String name) { diff --git a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart index 296e6adc..d7b1d509 100644 --- a/lib/interpret_and_optimize/entities/pb_deny_list_node.dart +++ b/lib/interpret_and_optimize/entities/pb_deny_list_node.dart @@ -12,7 +12,7 @@ class PBDenyListNode extends PBIntermediateNode { ChildrenStrategy childrenStrategy = NoChildStrategy(); PBDenyListNode( String UUID, - Rectangle frame, { + Rectangle3D frame, { String name, }) : super( UUID, diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 4eb603e6..354546a4 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -61,7 +61,7 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode PBSharedInstanceIntermediateNode( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, this.SYMBOL_ID, this.sharedParamValues, diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart index eabff7bc..08a3af5f 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.g.dart @@ -10,8 +10,7 @@ PBSharedInstanceIntermediateNode _$PBSharedInstanceIntermediateNodeFromJson( Map json) { return PBSharedInstanceIntermediateNode( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), SYMBOL_ID: json['symbolID'] as String, sharedParamValues: (json['overrideValues'] as List) ?.map((e) => e == null @@ -40,7 +39,7 @@ Map _$PBSharedInstanceIntermediateNodeToJson( 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints?.toJson(), - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'symbolID': instance.SYMBOL_ID, diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index ce207115..b9733287 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -52,7 +52,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode PBSharedMasterNode( String UUID, - Rectangle frame, { + Rectangle3D frame, { this.originalRef, this.SYMBOL_ID, String name, diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart index 1b535f87..9f49e395 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart @@ -9,8 +9,7 @@ part of 'pb_shared_master_node.dart'; PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { return PBSharedMasterNode( json['UUID'] as String, - DeserializedRectangle.fromJson( - json['boundaryRectangle'] as Map), + Rectangle3D.fromJson(json['boundaryRectangle'] as Map), SYMBOL_ID: json['symbolID'] as String, name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( @@ -33,7 +32,7 @@ Map _$PBSharedMasterNodeToJson(PBSharedMasterNode instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints?.toJson(), - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'prototypeNodeUUID': instance.prototypeNode?.toJson(), diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index cd6afdb2..bfbb39c3 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -8,7 +8,6 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; // import 'dart:math'; @@ -58,9 +57,9 @@ abstract class PBIntermediateNode @JsonKey( ignore: false, name: 'boundaryRectangle', - fromJson: DeserializedRectangle.fromJson, - toJson: DeserializedRectangle.toJson) - Rectangle frame; + fromJson: Rectangle3D.fromJson, + toJson: Rectangle3D.toJson) + Rectangle3D frame; // @JsonKey(ignore: true) // PBGenerationViewData get managerData => currentContext.tree; @@ -88,7 +87,7 @@ abstract class PBIntermediateNode if (constraints == null) { logger.debug( - 'Constraints are null for $runtimeType, assigning it default constraints'); + 'Constraints are null for $runtimeType-$name, assigning it default constraints'); constraints = PBIntermediateConstraints.defaultConstraints(); } // _attributes = []; @@ -137,14 +136,6 @@ abstract class PBIntermediateNode .any((child) => child.attributeName == attributeName); } - /// Adds child to node. - // void addChild(PBIntermediateNode node) { - // childrenStrategy.addChild(this, node); - - // /// Checking the constrains of the [node] being added to the tree, smoe of the - // /// constrains could be inherited to that section of the sub-tree. - // } - String getAttributeNameOf(PBIntermediateNode node) => childrenStrategy.attributeName; @@ -204,8 +195,6 @@ abstract class PBIntermediateNode extension PBPointLegacyMethod on Point { Point clone() => Point(x, y); - // TODO: This is a temporal fix ----- Not sure why there some sort of safe area for the y-axis?? - // (y.abs() - anotherPoint.y.abs()).abs() < 3 int compareTo(Point anotherPoint) => y == anotherPoint.y || (y.abs() - anotherPoint.y.abs()).abs() < 3 ? x.compareTo(anotherPoint.x) @@ -225,40 +214,53 @@ extension PBPointLegacyMethod on Point { return false; } - static Point topLeftFromJson(Map json) { - if (json == null) { - return null; - } - var x, y; - if (json.containsKey('boundaryRectangle')) { - x = json['boundaryRectangle']['x']; - y = json['boundaryRectangle']['y']; - } else { - x = json['x']; - y = json['y']; + static Map toJson(Point point) => {'x': point.x, 'y': point.y}; +} + +class Rectangle3D extends Rectangle { + ///For now we are unable to make any comparison in the z-axis, this + ///is primarly for sorting elements in [PBStackIntermediateLayout] to + ///place to correct [PBIntermediateNode]s on top. + num z; + Rectangle3D(num left, num top, num width, num height, this.z) + : super(left, top, width, height); + + @override + Rectangle boundingBox(Rectangle frame) { + var z = 0; + if (frame is Rectangle3D) { + z = max(z, (frame as Rectangle3D).z.toInt()); } - return Point(x, y); + return Rectangle3D.from2DRectangle(super.boundingBox(frame), z: z); } - static Point bottomRightFromJson(Map json) { - if (json == null) { - return null; - } - var x, y; - if (json.containsKey('boundaryRectangle')) { - x = json['boundaryRectangle']['x'] + json['boundaryRectangle']['width']; - y = json['boundaryRectangle']['y'] + json['boundaryRectangle']['height']; - } else { - x = json['x'] + json['width']; - y = json['y'] + json['height']; - } - return Point(x, y); + factory Rectangle3D.from2DRectangle(Rectangle rectangle, {int z = 0}) => + Rectangle3D( + rectangle.left, rectangle.top, rectangle.width, rectangle.height, z); + + static Rectangle3D fromJson(Map json) { + return Rectangle3D( + json['x'], json['y'], json['width'], json['height'], json['z'] ?? 0); } - static Map toJson(Point point) => {'x': point.x, 'y': point.y}; + factory Rectangle3D.fromPoints(Point a, Point b, {T z}) { + var left = min(a.x, b.x); + var width = (max(a.x, b.x) - left) as T; + var top = min(a.y, b.y); + var height = (max(a.y, b.y) - top) as T; + return Rectangle3D(left, top, width, height, z); + } + + static Map toJson(Rectangle3D Rectangle3D) => { + 'height': Rectangle3D.height, + 'width': Rectangle3D.width, + 'x': Rectangle3D.left, + 'y': Rectangle3D.top, + 'z': Rectangle3D.z + }; } -extension DeserializedRectangle on Rectangle { +extension DeserializedRectangle3D on Rectangle3D { bool _areXCoordinatesOverlapping( Point topLeftCorner0, Point bottomRightCorner0, @@ -279,35 +281,24 @@ extension DeserializedRectangle on Rectangle { bottomRightCorner1.y <= bottomRightCorner0.y && bottomRightCorner1.y >= topLeftCorner0.y; - bool isHorizontalTo(Rectangle frame) { + bool isHorizontalTo(Rectangle3D frame) { return (!(_areXCoordinatesOverlapping( topLeft, bottomRight, frame.topLeft, frame.bottomRight))) && _areYCoordinatesOverlapping( topLeft, bottomRight, frame.topLeft, frame.bottomRight); } - bool isVerticalTo(Rectangle frame) { + bool isVerticalTo(Rectangle3D frame) { return (!(_areYCoordinatesOverlapping( topLeft, bottomRight, frame.topLeft, frame.bottomRight))) && _areXCoordinatesOverlapping( topLeft, bottomRight, frame.topLeft, frame.bottomRight); } - bool isOverlappingTo(Rectangle frame) { + bool isOverlappingTo(Rectangle3D frame) { return (_areXCoordinatesOverlapping( topLeft, bottomRight, frame.topLeft, frame.bottomRight)) && _areYCoordinatesOverlapping( topLeft, bottomRight, frame.topLeft, frame.bottomRight); } - - static Rectangle fromJson(Map json) { - return Rectangle(json['x'], json['y'], json['width'], json['height']); - } - - static Map toJson(Rectangle rectangle) => { - 'height': rectangle.height, - 'width': rectangle.width, - 'x': rectangle.left, - 'y': rectangle.top - }; } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart index b6c6f75c..40583934 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.g.dart @@ -11,7 +11,7 @@ Map _$PBIntermediateNodeToJson(PBIntermediateNode instance) => 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints?.toJson(), - 'boundaryRectangle': DeserializedRectangle.toJson(instance.frame), + 'boundaryRectangle': Rectangle3D.toJson(instance.frame), 'style': instance.auxiliaryData?.toJson(), 'name': instance.name, 'hashCode': instance.hashCode, diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart index 4c40e5dc..eba02381 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart @@ -15,7 +15,7 @@ import 'package:uuid/uuid.dart'; /// This represents a node that should be a Layout; it contains a set of children arranged in a specific manner. It is also responsible for understanding its main axis spacing, and crossAxisAlignment. /// Superclass: PBIntermediateNode abstract class PBLayoutIntermediateNode extends PBIntermediateNode - implements PBInjectedIntermediate, PrototypeEnable { + implements PBInjectedIntermediate, PrototypeEnable, ChildrenObserver { ///The rules of the layout. MAKE SURE TO REGISTER THEIR CUSTOM RULES final List _layoutRules; @@ -33,92 +33,43 @@ abstract class PBLayoutIntermediateNode extends PBIntermediateNode Map alignment = {}; - PBLayoutIntermediateNode(String UUID, Rectangle frame, this._layoutRules, + PBLayoutIntermediateNode(String UUID, Rectangle3D frame, this._layoutRules, this._exceptions, String name, {this.prototypeNode, PBIntermediateConstraints constraints}) : super(UUID ?? Uuid().v4(), frame, name, constraints: constraints) { childrenStrategy = MultipleChildStrategy('children'); } - ///Replace the current children with the [children] - // void replaceChildren(List children, PBContext context) { - // if (children.isNotEmpty) { - // this.children = children; - // resize(context); - // } else { - // logger.warning( - // 'Trying to add a list of children to the $runtimeType that is either null or empty'); - // } - // } - - // @override - // void addChild(node){ - // resize(context) - // super.addChild(node); - // } - - /// Replace the child at `index` for `replacement`. - /// Returns true if the replacement wsa succesful, false otherwise. - // bool replaceChildAt(int index, PBIntermediateNode replacement) { - // if (children != null && children.length > index) { - // children[index] = replacement; - // return true; - // } - // return false; - // } - @override - void handleChildren(PBContext context) { - context.tree.addChildrenObeserver(UUID, (modification, children) { - if (modification == CHILDREN_MOD.CREATED && - modification == CHILDREN_MOD.REMOVED) { + void childrenModified(List children, [PBContext context]) { + if (children != null && children.isNotEmpty) { + if(context != null){ resize(context, children); } - }); - super.handleChildren(context); + sortChildren(children); + } } void resize(PBContext context, [List children]) { - children = - children ?? context.tree.edges(this); + children = children ?? context.tree.edges(this); if (children.isEmpty) { logger .warning('There should be children in the layout so it can resize.'); return; } - // var minX = (children[0]).frame.topLeft.x, - // minY = (children[0]).frame.topLeft.y, - // maxX = (children[0]).frame.bottomRight.x, - // maxY = (children[0]).frame.bottomRight.y; - // for (var child in children) { - // minX = min((child).frame.topLeft.x, minX); - // minY = min((child).frame.topLeft.y, minY); - // maxX = max((child).frame.bottomRight.x, maxX); - // maxY = max((child).frame.bottomRight.y, maxY); - // } children.forEach((child) => frame = frame.boundingBox(child.frame)); - // frame = Rectangle.fromPoints(Point(minX, minY), Point(maxX, maxY)); } - ///Remove Child - // bool removeChildren(PBIntermediateNode node, PBContext context) { - // if (children.contains(node)) { - // children.remove(node); - // } - // resize(context); - // return false; - // } - ///Sort children - // void sortChildren() => children.sort( - // (child0, child1) => child0.frame.topLeft.compareTo(child1.frame.topLeft)); + void sortChildren(List children) => children.sort( + (child0, child1) => child0.frame.topLeft.compareTo(child1.frame.topLeft)); ///The [PBLayoutIntermediateNode] contains a series of rules that determines if the children is part of that layout. All the children ///are going to have to meet the rules that the [PBLayoutIntermediateNode] presents. This method presents a way of comparing two children [PBIntermediateNode] ///the method is returning a boolean value that demonstrates if the two nodes satisfies the rules of the [PBLayoutIntermediateNode]. If ///a list of children need to be compared, use `allSatisfiesRules()`. - bool satisfyRules(PBContext context, - PBIntermediateNode currentNode, PBIntermediateNode nextNode) { + bool satisfyRules(PBContext context, PBIntermediateNode currentNode, + PBIntermediateNode nextNode) { ///First check if there is an exception then check that is satisfies all the rules. for (var exception in _exceptions) { if (exception.testException(currentNode, nextNode)) { diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart index eb2e66cf..1f3f19a4 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart @@ -10,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; /// Superclass: PBIntermediateNode abstract class PBVisualIntermediateNode extends PBIntermediateNode { PBVisualIntermediateNode( - String UUID, Rectangle rectangle, String name, + String UUID, Rectangle3D Rectangle3D, String name, {PBIntermediateConstraints constraints}) - : super(UUID, rectangle, name, constraints: constraints); + : super(UUID, Rectangle3D, name, constraints: constraints); } diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 295e8e7c..be5043fc 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -2,6 +2,7 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; @@ -10,10 +11,10 @@ import 'dart:math'; class PBContext { final PBConfiguration configuration; - Rectangle _screenFrame; - Rectangle get screenFrame => _screenFrame; - set screenFrame(Rectangle frame){ - canvasFrame ??= Rectangle.fromPoints(frame.topLeft, frame.bottomRight); + Rectangle3D _screenFrame; + Rectangle3D get screenFrame => _screenFrame; + set screenFrame(Rectangle3D frame){ + canvasFrame ??= Rectangle3D.fromPoints(frame.topLeft, frame.bottomRight); _screenFrame = frame; } @@ -26,7 +27,7 @@ class PBContext { /// Some of the scenarios the focusAreaWould change: /// - When the appbar is used, it should shrink the canvas top point to make room for the appbar /// - When another stack is declared, its TLC becomes the new canvas TLC(same for BRC). - Rectangle canvasFrame; + Rectangle3D canvasFrame; /// The [constextConstrains] represents the costraints that would be inherited by a section of the tree. /// diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart deleted file mode 100644 index 2fb1f4d9..00000000 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; - -/// Iterating the Intermediate Tree by DFS -class IntermediateDFSIterator - implements Iterator { - final PBIntermediateTree _tree; - - E _currentElement; - - List _stack; - - IntermediateDFSIterator(this._tree, {E startingNode}) { - var initNode = startingNode ?? _tree.rootNode; - if (initNode == null) { - throw NullThrownError(); - } - _stack = [initNode]; - } - @override - bool moveNext() { - if (_stack.isNotEmpty) { - _currentElement = _stack.removeAt(0); - _stack.addAll((_currentElement?.children ?? []).cast()); - return true; - } - return false; - } - - @override - E get current => _currentElement; -} diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart deleted file mode 100644 index bd094ce0..00000000 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; - -class IntermediateLayerIterator - implements Iterator> { - final PBIntermediateTree _tree; - List> _stack; - - @override - List get current => _current; - List _current; - - @override - bool moveNext() { - if (_stack.isNotEmpty) { - _current = _stack.removeAt(0); - _stack.add(_current - .expand((element) => element.children as Iterable)); - return true; - } - return false; - } - - IntermediateLayerIterator(this._tree, {E starting}) { - var initNode = starting ?? _tree.rootNode; - if (initNode == null) { - throw NullThrownError(); - } - _stack = [ - [initNode] - ]; - } -} diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index afdb9719..b8fab820 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -5,8 +5,6 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_dfs_iterator.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_layer_iterator.dart'; import 'package:quick_log/quick_log.dart'; import 'package:recase/recase.dart'; import 'package:tuple/tuple.dart'; @@ -152,9 +150,9 @@ class PBIntermediateTree extends DirectedGraph { _elementStorage.elementToTree[child.UUID] = _UUID; } }); - if (_childrenModObservers.containsKey(parent.id)) { - _childrenModObservers[parent.id].forEach( - (listener) => listener(CHILDREN_MOD.CREATED, children.toList())); + + if (parent is ChildrenObserver && context != null) { + (parent as ChildrenObserver).childrenModified(children, context); } return super.addEdges(parent, children); }; @@ -165,9 +163,8 @@ class PBIntermediateTree extends DirectedGraph { @override void removeEdges(Vertex parent, [List> children]) { - if (_childrenModObservers.containsKey(parent.id)) { - _childrenModObservers[parent.id].forEach((listener) => listener( - CHILDREN_MOD.REMOVED, children?.toList() ?? edges(parent).toList())); + if (parent is ChildrenObserver) { + (parent as ChildrenObserver).childrenModified(children, context); } super.removeEdges(parent, children); } @@ -256,28 +253,23 @@ class PBIntermediateTree extends DirectedGraph { PBIntermediateNode.fromJson(json['designNode'], null, tree); tree._rootNode = designNode; return tree; - - // List> childrenPointer = json['designNode']['children']; - - /// Deserialize the rootNode - /// Then make sure rootNode deserializes the rest of the tree. - // ..addEdges(child, parentList) - // ..tree_type = treeTypeFromJson(json['designNode']); } } -/// By extending the class, any node could be used in any iterator to traverse its -/// internals. +/// This interface serves as a communication channel between the [PBIntermediateNTree] and [PBIntermediateNode]. /// -/// In the example of the [PBIntermediateNode], you can traverse the [PBIntermediateNode]s -/// children by using the [IntermediateDFSIterator]. Furthermore, this allows the -/// [PBIntermediateTree] to traverse through its nodes, leveraging the dart methods. -abstract class TraversableNode { - String attributeName; - E parent; - List children; +/// Any [PBIntermediateNode] that wants to peform any additional logic based on its children modification +/// has to implement [ChildrenObserver]. The method [childrenModified(children)] is going to be called anytime +/// the [PBIntermediateNode]'s children are removed/added. +abstract class ChildrenObserver { + /// Even notification of [children] have been modified. + /// + /// [context] could be `null` when when the [PBIntermediateTree] is being initialized. [ChildrenObserver] + /// can still modify the [children] but it would be unable to add/remove children. + void childrenModified(List children, [PBContext context]); } + enum CHILDREN_MOD { CREATED, REMOVED, MODIFIED } typedef ChildrenModEventHandler = void Function( diff --git a/lib/main.dart b/lib/main.dart index 5bef315b..9bf158e7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -23,6 +23,8 @@ import 'controllers/main_info.dart'; import 'package:yaml/yaml.dart'; import 'package:path/path.dart' as p; +import 'interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; + final designToPBDLServices = [ SketchToPBDLService(), FigmaToPBDLService(), @@ -127,7 +129,7 @@ ${parser.usage} context.project = pbProject; /// Assuming that the [tree.rootNode] has the dimensions of the screen. - context.screenFrame = Rectangle.fromPoints( + context.screenFrame = Rectangle3D.fromPoints( tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); context.tree = tree; tree.context = context; From 6df7db04ed1514eb09601f43be62ff69987c7e67 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sat, 21 Aug 2021 15:46:16 -0500 Subject: [PATCH 328/404] WIP fix async issues with dependencies --- lib/controllers/interpret.dart | 3 +++ .../pb_prototype_aggregation_service.dart | 12 ++++++----- lib/main.dart | 20 +++++++++++++------ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 13f13e68..53c09a99 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -57,6 +57,9 @@ class Interpret { aitServiceBuilder ??= AITServiceBuilder(aitHandlers); var elementStorage = ElementStorage(); + elementStorage.elementToTree[tree.rootNode.UUID] = tree.UUID; + elementStorage.treeUUIDs[tree.UUID] = tree; + /// This is a workaround for adding missing information to either the [PBContext] or any of the /// [PBIntermediateNode]s. aitServiceBuilder.addTransformation( diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index 5dffbbc3..0728890b 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -63,7 +63,9 @@ class PBPrototypeAggregationService { elementStorage.treeUUIDs[elementStorage.elementToTree[target.UUID]]; var dependentTree = elementStorage.treeUUIDs[elementStorage.elementToTree[dependent.UUID]]; - if (dependentTree != targetTree) { + if (targetTree != null && + dependentTree != null && + dependentTree != targetTree) { dependentTree.addDependent(targetTree); } } @@ -74,8 +76,8 @@ class PBPrototypeAggregationService { // TODO: refactor the structure if (iNode == null) { return iNode; - } else{ - var destHolder = PBDestHolder( + } else { + var destHolder = PBDestHolder( null, iNode.frame, (iNode as PBInheritedIntermediate).prototypeNode, @@ -85,7 +87,7 @@ class PBPrototypeAggregationService { context.tree.addEdges(destHolder, [iNode]); return destHolder; } - + // else if (iNode is PBInheritedIntermediate) { // var destHolder = PBDestHolder( // null, @@ -139,7 +141,7 @@ class PBPrototypeAggregationService { for (var _pNode in _unregNodes) { if (_pNode.prototypeNode.destinationUUID == node.UUID) { _pNode.prototypeNode.destinationName = node.name; - _addDependent(_pNode as PBIntermediateNode, node); + _addDependent(node, _pNode as PBIntermediateNode); } } } diff --git a/lib/main.dart b/lib/main.dart index 5bef315b..053d0ac6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/generation/flutter_project_builder/flutter_project import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart'; @@ -122,20 +123,27 @@ ${parser.usage} await fpb.preGenTasks(); await indexFileFuture; - await Future.wait(pbProject.forest.map((tree) { + var trees = []; + + for (var tree in pbProject.forest) { var context = PBContext(processInfo.configuration); context.project = pbProject; - /// Assuming that the [tree.rootNode] has the dimensions of the screen. context.screenFrame = Rectangle.fromPoints( tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); + context.tree = tree; tree.context = context; + tree.forEach((child) => child.handleChildren(context)); - return interpretService - .interpretAndOptimize(tree, context, pbProject) - .then((tree) => fpb.genAITree(tree, context)); - }).toList()); + + trees.add( + await interpretService.interpretAndOptimize(tree, context, pbProject)); + } + + for (var tree in trees) { + await fpb.genAITree(tree, tree.context); + } exitCode = 0; } From e2250407ea4c44064bed5df299dfec3fa01be11f Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sun, 22 Aug 2021 09:57:09 -0500 Subject: [PATCH 329/404] Chande type of `InheritedContainer` to match PBDL type Casting list to `PBIntermediateNode` when removing edges in prototype service --- lib/generation/prototyping/pb_prototype_linker_service.dart | 2 +- lib/interpret_and_optimize/entities/inherited_container.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/generation/prototyping/pb_prototype_linker_service.dart b/lib/generation/prototyping/pb_prototype_linker_service.dart index 9ae29bb1..588951ae 100644 --- a/lib/generation/prototyping/pb_prototype_linker_service.dart +++ b/lib/generation/prototyping/pb_prototype_linker_service.dart @@ -41,7 +41,7 @@ class PBPrototypeLinkerService { var pNode = _aggregationService.populatePrototypeNode(context, currentNode); if (pNode != null) { context.tree.addEdges(pNode.parent, [pNode]); - context.tree.removeEdges(pNode.parent, [currentNode]); + context.tree.removeEdges(pNode.parent, [currentNode]); } } } diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 6a872a18..59b1dbd6 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -33,7 +33,7 @@ class InheritedContainer extends PBVisualIntermediateNode @override @JsonKey() - String type = 'Rectangle3D'; + String type = 'rectangle'; @override @JsonKey(ignore: true) From 32641af0763f10994164a63e8b859fd01325df27 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sun, 22 Aug 2021 12:46:51 -0500 Subject: [PATCH 330/404] Add name to `PBDestHolder` so it can be registered by tags --- .../prototyping/pb_prototype_aggregation_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index 0728890b..cee8f602 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -81,7 +81,7 @@ class PBPrototypeAggregationService { null, iNode.frame, (iNode as PBInheritedIntermediate).prototypeNode, - ); + )..name = 'Dest_${iNode.name}'; // Save parent pointer of `iNode` destHolder.parent = iNode.parent; context.tree.addEdges(destHolder, [iNode]); From 092ef37ede540f1099c43389c0f2ca155a3d75e5 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sun, 22 Aug 2021 21:14:43 -0500 Subject: [PATCH 331/404] Configured the way generation is run to ensure imports are properly generated --- .../flutter_project_builder.dart | 10 ++++++---- .../entities/pb_shared_master_node.dart | 2 +- lib/main.dart | 6 +++++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index 39826af5..14b992e5 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -126,16 +126,18 @@ class FlutterProjectBuilder { ; } - Future genAITree(PBIntermediateTree tree, PBContext context) async { + Future genAITree( + PBIntermediateTree tree, PBContext context, bool isDryRun) async { if (!_configured) { /// Avoid changing the [_configured] from here, it might lead to async changes on the var throw Error(); } - await generationConfiguration.generateTree(tree, project, context, true); - await generationConfiguration.generateTree(tree, project, context, false); + await generationConfiguration.generateTree( + tree, project, context, isDryRun); generationConfiguration.generatePlatformAndOrientationInstance(project); - await formatProject(project.projectAbsPath, projectDir: MainInfo().outputPath); + await formatProject(project.projectAbsPath, + projectDir: MainInfo().outputPath); } } diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index b9733287..9d5aa2f3 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -145,7 +145,7 @@ class PBSharedParameterProp { // Populate `value` of Override Property since it is an [IntermediateNode] fromJson.value = json['value'] == null ? null - : PBIntermediateNode.fromJson(json, parent, tree); + : PBIntermediateNode.fromJson(json['value'], parent, tree); return fromJson; } diff --git a/lib/main.dart b/lib/main.dart index 2bb5b66a..e50835f3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -145,7 +145,11 @@ ${parser.usage} } for (var tree in trees) { - await fpb.genAITree(tree, tree.context); + await fpb.genAITree(tree, tree.context, true); + } + + for (var tree in trees) { + await fpb.genAITree(tree, tree.context, false); } exitCode = 0; From aa5c0b5f8390ff4a569a26586a32fbde90580847 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Sun, 22 Aug 2021 22:39:25 -0600 Subject: [PATCH 332/404] WIP switch constraints as an optional. This prevents the conditional statement in PBIntermediateNode to assign default constraints to all the nodes coming from JSON. JSON nodes get assign their constraints after being deserialize (node..constraints = some_constraints). --- .../entities/inherited_bitmap.dart | 3 ++- .../entities/inherited_bitmap.g.dart | 8 ++++---- .../entities/inherited_circle.dart | 2 ++ .../entities/inherited_circle.g.dart | 8 ++++---- .../entities/inherited_container.dart | 2 ++ .../entities/inherited_container.g.dart | 8 ++++---- lib/interpret_and_optimize/entities/inherited_oval.dart | 3 ++- .../entities/inherited_oval.g.dart | 8 ++++---- .../entities/inherited_polygon.dart | 2 ++ .../entities/inherited_polygon.g.dart | 8 ++++---- .../entities/inherited_scaffold.dart | 4 ++-- .../entities/inherited_scaffold.g.dart | 8 ++++---- .../entities/inherited_shape_group.dart | 2 ++ .../entities/inherited_shape_group.g.dart | 8 ++++---- .../entities/inherited_shape_path.dart | 2 ++ .../entities/inherited_shape_path.g.dart | 8 ++++---- lib/interpret_and_optimize/entities/inherited_star.dart | 3 ++- .../entities/inherited_star.g.dart | 8 ++++---- .../entities/inherited_triangle.dart | 2 ++ .../entities/inherited_triangle.g.dart | 8 ++++---- .../entities/injected_container.dart | 1 + .../entities/injected_container.g.dart | 8 ++++---- .../entities/intermediate_border_info.dart | 1 + .../entities/layouts/group/group.dart | 9 --------- .../entities/pb_shared_master_node.dart | 2 ++ .../entities/pb_shared_master_node.g.dart | 8 ++++---- 26 files changed, 72 insertions(+), 62 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index 4e3d186a..e40f3fff 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -41,11 +41,12 @@ class InheritedBitmap extends PBVisualIntermediateNode Map originalRef; InheritedBitmap(String UUID, Rectangle3D frame, - {this.originalRef, String name, this.referenceImage, this.prototypeNode}) + {this.originalRef, String name, this.referenceImage, this.prototypeNode, PBIntermediateConstraints constraints}) : super( UUID, frame, name, + constraints: constraints ) { generator = PBBitmapGenerator(); childrenStrategy = NoChildStrategy(); diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart index c9db6632..1d20b006 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.g.dart @@ -14,12 +14,12 @@ InheritedBitmap _$InheritedBitmapFromJson(Map json) { referenceImage: json['imageReference'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/inherited_circle.dart b/lib/interpret_and_optimize/entities/inherited_circle.dart index 43d37bfe..78f69ef0 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.dart @@ -41,10 +41,12 @@ class InheritedCircle extends PBVisualIntermediateNode Point alignX, Point alignY, this.prototypeNode, + PBIntermediateConstraints constraints }) : super( UUID, frame, name, + constraints: constraints ) { generator = PBBitmapGenerator(); childrenStrategy = TempChildrenStrategy('child'); diff --git a/lib/interpret_and_optimize/entities/inherited_circle.g.dart b/lib/interpret_and_optimize/entities/inherited_circle.g.dart index 2cb1d52e..e403ca09 100644 --- a/lib/interpret_and_optimize/entities/inherited_circle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_circle.g.dart @@ -13,12 +13,12 @@ InheritedCircle _$InheritedCircleFromJson(Map json) { name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 59b1dbd6..98f7362a 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -48,10 +48,12 @@ class InheritedContainer extends PBVisualIntermediateNode double alignY, this.isBackgroundVisible = true, this.prototypeNode, + PBIntermediateConstraints constraints }) : super( UUID, frame, name, + constraints: constraints ) { generator = PBContainerGenerator(); childrenStrategy = TempChildrenStrategy('child'); diff --git a/lib/interpret_and_optimize/entities/inherited_container.g.dart b/lib/interpret_and_optimize/entities/inherited_container.g.dart index 5302d986..85337ec1 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.g.dart @@ -14,12 +14,12 @@ InheritedContainer _$InheritedContainerFromJson(Map json) { isBackgroundVisible: json['isBackgroundVisible'] as bool ?? true, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/inherited_oval.dart b/lib/interpret_and_optimize/entities/inherited_oval.dart index 382a47d9..0eb2bea2 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.dart @@ -44,7 +44,8 @@ class InheritedOval extends PBVisualIntermediateNode String name, Uint8List image, this.prototypeNode, - }) : super(UUID, frame, name) { + PBIntermediateConstraints constraints + }) : super(UUID, frame, name, constraints: constraints) { generator = PBBitmapGenerator(); if (image != null) { ImageReferenceStorage().addReferenceAndWrite( diff --git a/lib/interpret_and_optimize/entities/inherited_oval.g.dart b/lib/interpret_and_optimize/entities/inherited_oval.g.dart index 559bf072..74da3458 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.g.dart @@ -13,12 +13,12 @@ InheritedOval _$InheritedOvalFromJson(Map json) { name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.dart b/lib/interpret_and_optimize/entities/inherited_polygon.dart index 623a7f7a..fa2b607b 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.dart @@ -45,10 +45,12 @@ class InheritedPolygon extends PBVisualIntermediateNode name, Uint8List image, this.prototypeNode, + PBIntermediateConstraints constraints }) : super( UUID, frame, name, + constraints: constraints ) { generator = PBBitmapGenerator(); childrenStrategy = NoChildStrategy(); diff --git a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart index 6e1e3c4d..1887bf49 100644 --- a/lib/interpret_and_optimize/entities/inherited_polygon.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_polygon.g.dart @@ -13,12 +13,12 @@ InheritedPolygon _$InheritedPolygonFromJson(Map json) { name: json['name'], prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index f366ff98..56fb8fba 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -44,8 +44,8 @@ class InheritedScaffold extends PBVisualIntermediateNode InheritedScaffold( String UUID, Rectangle3D frame, String name, this.originalRef, - {this.isHomeScreen, this.prototypeNode}) - : super(UUID, frame, name) { + {this.isHomeScreen, this.prototypeNode, PBIntermediateConstraints constraints}) + : super(UUID, frame, name, constraints: constraints) { generator = PBScaffoldGenerator(); childrenStrategy = MultipleChildStrategy('body'); } diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart index 69885423..1da5a313 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.g.dart @@ -15,12 +15,12 @@ InheritedScaffold _$InheritedScaffoldFromJson(Map json) { isHomeScreen: json['isFlowHome'] as bool ?? false, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index ea8227cb..ce06c3fb 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -44,10 +44,12 @@ class InheritedShapeGroup extends PBVisualIntermediateNode String name, Uint8List image, this.prototypeNode, + PBIntermediateConstraints constraints }) : super( UUID, frame, name, + constraints: constraints ) { generator = PBBitmapGenerator(); childrenStrategy = NoChildStrategy(); diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart index 3aa17d4d..2db4922b 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.g.dart @@ -13,12 +13,12 @@ InheritedShapeGroup _$InheritedShapeGroupFromJson(Map json) { name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.dart index 6d3b7386..c7daa326 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.dart @@ -46,10 +46,12 @@ class InheritedShapePath extends PBVisualIntermediateNode String name, Uint8List image, this.prototypeNode, + PBIntermediateConstraints constraints }) : super( UUID, frame, name, + constraints: constraints ) { generator = PBBitmapGenerator(); childrenStrategy = NoChildStrategy(); diff --git a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart index 3d048b65..ab8a97cc 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_path.g.dart @@ -13,12 +13,12 @@ InheritedShapePath _$InheritedShapePathFromJson(Map json) { name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/inherited_star.dart b/lib/interpret_and_optimize/entities/inherited_star.dart index 5f63b8ee..6b988920 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.dart @@ -34,7 +34,6 @@ class InheritedStar extends PBVisualIntermediateNode String type = 'star'; - @override @JsonKey(ignore: true) Map originalRef; @@ -46,10 +45,12 @@ class InheritedStar extends PBVisualIntermediateNode name, Uint8List image, this.prototypeNode, + PBIntermediateConstraints constraints }) : super( UUID, frame, name, + constraints: constraints ) { generator = PBBitmapGenerator(); childrenStrategy = NoChildStrategy(); diff --git a/lib/interpret_and_optimize/entities/inherited_star.g.dart b/lib/interpret_and_optimize/entities/inherited_star.g.dart index 777f273b..c4f81098 100644 --- a/lib/interpret_and_optimize/entities/inherited_star.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_star.g.dart @@ -13,12 +13,12 @@ InheritedStar _$InheritedStarFromJson(Map json) { name: json['name'], prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.dart b/lib/interpret_and_optimize/entities/inherited_triangle.dart index 2c5b506f..f8d88ccf 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.dart @@ -45,10 +45,12 @@ class InheritedTriangle extends PBVisualIntermediateNode String name, Uint8List image, this.prototypeNode, + PBIntermediateConstraints constraints }) : super( UUID, frame, name, + constraints: constraints ) { generator = PBBitmapGenerator(); childrenStrategy = NoChildStrategy(); diff --git a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart index 9408fe7c..0bafb06d 100644 --- a/lib/interpret_and_optimize/entities/inherited_triangle.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_triangle.g.dart @@ -13,12 +13,12 @@ InheritedTriangle _$InheritedTriangleFromJson(Map json) { name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index 802adfb1..eb2d093a 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -43,6 +43,7 @@ class InjectedContainer extends PBVisualIntermediateNode String color, this.prototypeNode, this.type, + PBIntermediateConstraints constraints }) : super( UUID, frame, diff --git a/lib/interpret_and_optimize/entities/injected_container.g.dart b/lib/interpret_and_optimize/entities/injected_container.g.dart index edc85e40..8e69d5cf 100644 --- a/lib/interpret_and_optimize/entities/injected_container.g.dart +++ b/lib/interpret_and_optimize/entities/injected_container.g.dart @@ -14,12 +14,12 @@ InjectedContainer _$InjectedContainerFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson(json['prototypeNode'] as String), type: json['type'] as String, - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( diff --git a/lib/interpret_and_optimize/entities/intermediate_border_info.dart b/lib/interpret_and_optimize/entities/intermediate_border_info.dart index 91b36acf..acce94d0 100644 --- a/lib/interpret_and_optimize/entities/intermediate_border_info.dart +++ b/lib/interpret_and_optimize/entities/intermediate_border_info.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; import 'package:json_annotation/json_annotation.dart'; diff --git a/lib/interpret_and_optimize/entities/layouts/group/group.dart b/lib/interpret_and_optimize/entities/layouts/group/group.dart index 4dd65ff1..1c233dd4 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/group.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/group.dart @@ -8,9 +8,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layo import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; // @JsonSerializable(ignoreUnannotated: true, explicitToJson: true) @@ -52,11 +50,4 @@ abstract class Group extends PBLayoutIntermediateNode assert(false, 'Attempted to generateLayout for class type [$runtimeType]'); return null; } - - // @override - // PBIntermediateNode createIntermediateNode(Map json, - // PBIntermediateNode parent, PBIntermediateTree tree) => - // (Group.fromJson(json) as Group) - // ..mapRawChildren(json, tree) - // ..originalRef = json; } diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 9d5aa2f3..4a684cba 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -58,10 +58,12 @@ class PBSharedMasterNode extends PBVisualIntermediateNode String name, this.overridableProperties, this.prototypeNode, + PBIntermediateConstraints constraints }) : super( UUID, frame, name, + constraints: constraints ) { overridableProperties ??= []; try { diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart index 9f49e395..19891548 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.g.dart @@ -14,12 +14,12 @@ PBSharedMasterNode _$PBSharedMasterNodeFromJson(Map json) { name: json['name'] as String, prototypeNode: PrototypeNode.prototypeNodeFromJson( json['prototypeNodeUUID'] as String), - ) - ..subsemantic = json['subsemantic'] as String - ..constraints = json['constraints'] == null + constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( - json['constraints'] as Map) + json['constraints'] as Map), + ) + ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( From e5118b647130fdc96fec8b73c1cd832d9128adb8 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Mon, 23 Aug 2021 17:33:09 -0500 Subject: [PATCH 333/404] Fix imports not generating on certain files --- .../prototyping/pb_prototype_aggregation_service.dart | 2 +- lib/generation/prototyping/pb_prototype_gen.dart | 6 +++++- .../prototyping/pb_prototype_linker_service.dart | 2 +- .../entities/layouts/group/group.dart | 11 +++++++++-- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/generation/prototyping/pb_prototype_aggregation_service.dart b/lib/generation/prototyping/pb_prototype_aggregation_service.dart index cee8f602..ada26788 100644 --- a/lib/generation/prototyping/pb_prototype_aggregation_service.dart +++ b/lib/generation/prototyping/pb_prototype_aggregation_service.dart @@ -50,7 +50,7 @@ class PBPrototypeAggregationService { if (page == null) { _unregNodes.add(node as PrototypeEnable); } else { - _addDependent(node, page); + _addDependent(page, node); } } _unregNodes.removeWhere( diff --git a/lib/generation/prototyping/pb_prototype_gen.dart b/lib/generation/prototyping/pb_prototype_gen.dart index 17608837..0de327c1 100644 --- a/lib/generation/prototyping/pb_prototype_gen.dart +++ b/lib/generation/prototyping/pb_prototype_gen.dart @@ -3,6 +3,7 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:recase/recase.dart'; class PBPrototypeGenerator extends PBGenerator { PrototypeNode prototypeNode; @@ -14,7 +15,10 @@ class PBPrototypeGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext context) { - var name = _storage.getPageNodeById(prototypeNode.destinationUUID)?.name; + var name = _storage + .getPageNodeById(prototypeNode.destinationUUID) + ?.name + ?.pascalCase; var tree = context.tree; var sourceChildren = tree.childrenOf(source); if (name != null && name.isNotEmpty) { diff --git a/lib/generation/prototyping/pb_prototype_linker_service.dart b/lib/generation/prototyping/pb_prototype_linker_service.dart index 588951ae..1737466e 100644 --- a/lib/generation/prototyping/pb_prototype_linker_service.dart +++ b/lib/generation/prototyping/pb_prototype_linker_service.dart @@ -26,7 +26,7 @@ class PBPrototypeLinkerService { if (element is InheritedScaffold) { await _prototypeStorage.addPageNode(element, context); } else if (element is PrototypeEnable) { - if (((element)).prototypeNode?.destinationUUID != null && + if (element.prototypeNode?.destinationUUID != null && (element).prototypeNode.destinationUUID.isNotEmpty) { await addAndPopulatePrototypeNode(element, rootNode, context); } diff --git a/lib/interpret_and_optimize/entities/layouts/group/group.dart b/lib/interpret_and_optimize/entities/layouts/group/group.dart index 1c233dd4..3df2e68a 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/group.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/group.dart @@ -10,7 +10,6 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:json_annotation/json_annotation.dart'; - // @JsonSerializable(ignoreUnannotated: true, explicitToJson: true) /// A temporary node that must be removed @@ -35,7 +34,15 @@ abstract class Group extends PBLayoutIntermediateNode String name, this.prototypeNode, PBIntermediateConstraints constraints, - }) : super(UUID, frame, [], [], name, constraints: constraints); + }) : super( + UUID, + frame, + [], + [], + name, + constraints: constraints, + prototypeNode: prototypeNode, + ); @override bool satisfyRules(PBContext context, PBIntermediateNode currentNode, From 840940fc41e66ddf45fadb3a3c8387812c520bb7 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Tue, 24 Aug 2021 12:03:18 -0500 Subject: [PATCH 334/404] WIP generating provider models --- .../state_management/provider_middleware.dart | 2 +- .../abstract_intermediate_node_factory.dart | 11 ++-- .../helpers/pb_state_management_helper.dart | 7 ++- .../helpers/pb_state_management_linker.dart | 51 ++++++++++++------- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index d16b4eb7..da1b3663 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -124,7 +124,7 @@ class ProviderMiddleware extends StateManagementMiddleware { // Generate node's states' view pages node.auxiliaryData?.stateGraph?.states?.forEach((state) { fileStrategy.commandCreated(WriteSymbolCommand( - 'TODO', + context.tree.UUID, // state.variation.node.currentContext.tree.UUID, state.variation.node.name.snakeCase, generationManager.generate(state.variation.node, context), diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index 3c9db8db..45af9c13 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -1,4 +1,3 @@ -import 'package:directed_graph/directed_graph.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_circle.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; @@ -65,7 +64,8 @@ class AbstractIntermediateNodeFactory { return tag; } - if (parent != null) { + interpretStateManagement(iNode, tree); + if (parent != null && iNode != null) { tree.addEdges(parent, [iNode]); } @@ -80,17 +80,18 @@ class AbstractIntermediateNodeFactory { /// /// Returns `null` if `node` is a non-default state management node, effectively removing `node` from the tree. /// Returns `node` if it is a default state management node or a non-state management node. - static PBIntermediateNode interpretStateManagement(PBIntermediateNode node) { + static PBIntermediateNode interpretStateManagement( + PBIntermediateNode node, PBIntermediateTree tree) { if (node is! PBSharedMasterNode) { return node; } var smHelper = PBStateManagementHelper(); if (smHelper.isValidStateNode(node.name)) { if (smHelper.isDefaultNode(node)) { - smHelper.interpretStateManagementNode(node); + smHelper.interpretStateManagementNode(node, tree); return node; } else { - smHelper.interpretStateManagementNode(node); + smHelper.interpretStateManagementNode(node, tree); return null; } } diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_helper.dart b/lib/interpret_and_optimize/helpers/pb_state_management_helper.dart index 8fdad3ec..694c8fa3 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_helper.dart @@ -1,5 +1,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_linker.dart'; /// Class that interprets state management nodes @@ -15,12 +17,13 @@ class PBStateManagementHelper { linker = PBStateManagementLinker(); } - void interpretStateManagementNode(PBIntermediateNode node) { + void interpretStateManagementNode( + PBIntermediateNode node, PBIntermediateTree tree) { if (isValidStateNode(node.name)) { var nodeName = _getNodeName(node.name); // TODO: these states will be used for phase 2 of state management var states = _getStates(node.name); - linker.processVariation(node, nodeName); + linker.processVariation(node, nodeName, tree); } } diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index ab3dcb96..5d8f8aea 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -1,7 +1,11 @@ +import 'dart:io'; + import 'package:parabeac_core/controllers/interpret.dart'; +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; @@ -40,7 +44,8 @@ class PBStateManagementLinker { /// Adds the `node` variation to the [DirectedStateGraph] of the /// default [PBIntermediateNode], or sets up `node` as default /// to receive [IntermediateStates] in its state graph. - void processVariation(PBIntermediateNode node, String rootNodeName) async { + void processVariation(PBIntermediateNode node, String rootNodeName, + PBIntermediateTree tree) async { // Assign `node` as default if (!containsElement(rootNodeName)) { _statemap[rootNodeName] = node; @@ -55,8 +60,8 @@ class PBStateManagementLinker { .forEach((state) => node.auxiliaryData.stateGraph.addState(state)); // Add old default node as state of new default node - stateQueue - .add(_interpretVariationNode(instanceNode).then((processedNode) { + stateQueue.add( + _interpretVariationNode(instanceNode, tree).then((processedNode) { var intermediateState = IntermediateState(variation: IntermediateVariation(processedNode)); node.auxiliaryData.stateGraph.addState(intermediateState); @@ -72,7 +77,7 @@ class PBStateManagementLinker { PBSymbolStorage().getSharedInstanceNodeBySymbolID(node.SYMBOL_ID); tempSym?.forEach((element) => element.isMasterState = true); } - stateQueue.add(_interpretVariationNode(node).then((processedNode) { + stateQueue.add(_interpretVariationNode(node, tree).then((processedNode) { var intermediateState = IntermediateState(variation: IntermediateVariation(processedNode)); _statemap[rootNodeName] @@ -86,20 +91,28 @@ class PBStateManagementLinker { /// Runs the state management [PBIntermediateNode] through /// the necessary interpretation services. Future _interpretVariationNode( - PBIntermediateNode node) async { - - // var builder = AITServiceBuilder( - // node.currentContext, (node as PBInheritedIntermediate).originalRef); - // builder - // .addTransformation(visualGenerationService.getIntermediateTree) - // .addTransformation((PBIntermediateTree tree, context) { - // /// Making sure the name of the tree was changed back - // tree.name = node.name; - // }) - // .addTransformation( - // PBPluginControlService().convertAndModifyPluginNodeTree) - // .addTransformation(PBLayoutGenerationService().extractLayouts) - // .addTransformation(PBAlignGenerationService().addAlignmentToLayouts); - // return builder.build().then((tree) => tree.rootNode); + PBIntermediateNode node, PBIntermediateTree tree) async { + var builder = AITServiceBuilder(); + builder + .addTransformation((PBIntermediateTree tree) { + var context = PBContext(MainInfo().configuration); + context.screenFrame = Rectangle3D.fromPoints( + tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); + + context.tree = tree; + tree.context = context; + + tree.forEach((element) => element.handleChildren(context)); + }) + // .addTransformation(visualGenerationService.getIntermediateTree) + .addTransformation((PBIntermediateTree tree, context) { + // / Making sure the name of the tree was changed back + tree.name = node.name; + }) + .addTransformation( + PBPluginControlService().convertAndModifyPluginNodeTree) + .addTransformation(PBLayoutGenerationService().extractLayouts) + .addTransformation(PBAlignGenerationService().addAlignmentToLayouts); + return builder.build(tree: tree).then((tree) => tree.rootNode); } } From 8092231493f4387659db992d59d0ce4771e13000 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Tue, 24 Aug 2021 16:52:09 -0500 Subject: [PATCH 335/404] Fix: Scaffold now adjusts `canvasFrame` if it detects an appbar. --- .../entities/inherited_scaffold.dart | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index 56fb8fba..c1342da4 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -44,7 +44,9 @@ class InheritedScaffold extends PBVisualIntermediateNode InheritedScaffold( String UUID, Rectangle3D frame, String name, this.originalRef, - {this.isHomeScreen, this.prototypeNode, PBIntermediateConstraints constraints}) + {this.isHomeScreen, + this.prototypeNode, + PBIntermediateConstraints constraints}) : super(UUID, frame, name, constraints: constraints) { generator = PBScaffoldGenerator(); childrenStrategy = MultipleChildStrategy('body'); @@ -63,6 +65,19 @@ class InheritedScaffold extends PBVisualIntermediateNode @override void handleChildren(PBContext context) { var children = getAllAtrributeNamed(context.tree, 'body'); + + var appBar = getAttributeNamed(context.tree, 'appBar'); + if (appBar != null) { + context.canvasFrame = Rectangle3D( + context.screenFrame.left, + appBar.frame.bottomRight.y, + context.screenFrame.width, + context.screenFrame.height - appBar.frame.height, + 0, + ); + frame = context.canvasFrame; + } + // Top-most stack should have scaffold's frame to align children properly var groupAtt = FrameGroup(null, frame) ..name = '$name-Group' @@ -71,7 +86,6 @@ class InheritedScaffold extends PBVisualIntermediateNode context.tree.addEdges(groupAtt, children.map((child) => child).toList()); // Keep appbar and tabbar - var appBar = getAttributeNamed(context.tree, 'appBar'); var tabBar = getAttributeNamed(context.tree, 'bottomNavigationBar'); context.tree.replaceChildrenOf(this, From dd04f826160d435b7e3d5d7c0c2d48856c4ed6a4 Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Tue, 24 Aug 2021 20:47:45 -0600 Subject: [PATCH 336/404] WIP _setConstraints method was causing errors in how constraints where being processed. --- .../helpers/align_strategy.dart | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 3ef7e47a..ae292a78 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -25,20 +25,20 @@ abstract class AlignStrategy { /// When [context.fixedWidth] is not `null`, se assign the [context.fixedWidth] to subtree and /// we make [node.constraints.pinLeft] = `true` and [node.constraints.pingRight] = `false`. void _setConstraints(PBContext context, T node) { - context.contextConstraints?.fixedHeight ??= node.constraints?.fixedHeight; - context.contextConstraints?.fixedWidth ??= node.constraints?.fixedWidth; + // context.contextConstraints?.fixedHeight ??= node.constraints?.fixedHeight; + // context.contextConstraints?.fixedWidth ??= node.constraints?.fixedWidth; - if (context.contextConstraints.fixedHeight != null) { - node.constraints?.fixedHeight = context.contextConstraints?.fixedHeight; - node.constraints?.pinTop = true; - node.constraints?.pinBottom = false; - } + // if (!context.contextConstraints.fixedHeight) { + // node.constraints?.fixedHeight = context.contextConstraints?.fixedHeight; + // node.constraints?.pinTop = true; + // node.constraints?.pinBottom = false; + // } - if (context.contextConstraints.fixedWidth != null) { - node.constraints?.fixedWidth = context.contextConstraints.fixedWidth; - node.constraints?.pinLeft = true; - node.constraints?.pinRight = false; - } + // if (!context.contextConstraints.fixedWidth) { + // node.constraints?.fixedWidth = context.contextConstraints.fixedWidth; + // node.constraints?.pinLeft = true; + // node.constraints?.pinRight = false; + // } } } From 5daca713586b2bbbaf5da076ee269db03fa8db93 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 25 Aug 2021 08:04:47 -0500 Subject: [PATCH 337/404] Update pbdl submodule to point to `merge/main-constraints` --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index 252b8e42..51d3084a 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 252b8e423c81d0265fcbc9f61c92f8b777d33acd +Subproject commit 51d3084ae4a2cca8f71a31fba144859e73ddbee5 From a64f519f8fab505a2bdab31704de2df9f7dd2963 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 25 Aug 2021 08:54:03 -0500 Subject: [PATCH 338/404] Remove SAC submodule --- SketchAssetConverter | 1 - 1 file changed, 1 deletion(-) delete mode 160000 SketchAssetConverter diff --git a/SketchAssetConverter b/SketchAssetConverter deleted file mode 160000 index 1b5effbd..00000000 --- a/SketchAssetConverter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1b5effbd220ff03015bc4b288184005e4443f056 From ec332cdbf98393c8076f08b196bb9110ef44c4c8 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 25 Aug 2021 16:24:44 -0500 Subject: [PATCH 339/404] Hotfix to format override values with `$` in the name --- .../entities/pb_shared_instance.dart | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 354546a4..249b8ee6 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -50,7 +50,6 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @JsonKey() String type = 'shared_instance'; - List overrideValues; // quick lookup based on UUID_type Map overrideValuesMap = {}; @@ -74,9 +73,10 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode name, ) { generator = PBSymbolInstanceGenerator(); - + childrenStrategy = NoChildStrategy(); alignStrategy = NoAlignment(); + /// if [sharedParamValues] sets [overrideValues], then only pass one // overrideValues = sharedParamValues.map((v) { // var symOvrValue = @@ -95,8 +95,20 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode @override PBIntermediateNode createIntermediateNode(Map json, - PBIntermediateNode parent, PBIntermediateTree tree) => - PBSharedInstanceIntermediateNode.fromJson(json); + PBIntermediateNode parent, PBIntermediateTree tree) { + var instance = PBSharedInstanceIntermediateNode.fromJson(json); + _formatOverrideVals( + (instance as PBSharedInstanceIntermediateNode).sharedParamValues); + return instance; + } + + void _formatOverrideVals(List vals) { + vals.forEach((overrideValue) { + if (overrideValue.type == 'stringValue') { + overrideValue.value = overrideValue.value.replaceAll('\$', '\\\$'); + } + }); + } } @JsonSerializable() From ecb2b5fa038ed5a4905215ee8c04d994203bfe5a Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 25 Aug 2021 19:39:44 -0600 Subject: [PATCH 340/404] WIP fixed node & context inherited constraints --- .../helpers/align_strategy.dart | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index ae292a78..2058be64 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -24,21 +24,25 @@ abstract class AlignStrategy { /// assign the [node.constraints.pinTop] = `true` and [node.constraints.pinBottom] = `false`. /// When [context.fixedWidth] is not `null`, se assign the [context.fixedWidth] to subtree and /// we make [node.constraints.pinLeft] = `true` and [node.constraints.pingRight] = `false`. - void _setConstraints(PBContext context, T node) { - // context.contextConstraints?.fixedHeight ??= node.constraints?.fixedHeight; - // context.contextConstraints?.fixedWidth ??= node.constraints?.fixedWidth; + void _setConstraints(PBContext context, T node) { + if(node.constraints.fixedHeight){ + context.contextConstraints.fixedHeight = true; + } + if(node.constraints.fixedWidth){ + context.contextConstraints.fixedWidth = true; + } - // if (!context.contextConstraints.fixedHeight) { - // node.constraints?.fixedHeight = context.contextConstraints?.fixedHeight; - // node.constraints?.pinTop = true; - // node.constraints?.pinBottom = false; - // } + if (context.contextConstraints.fixedHeight) { + node.constraints?.fixedHeight = context.contextConstraints?.fixedHeight; + node.constraints?.pinTop = true; + node.constraints?.pinBottom = false; + } - // if (!context.contextConstraints.fixedWidth) { - // node.constraints?.fixedWidth = context.contextConstraints.fixedWidth; - // node.constraints?.pinLeft = true; - // node.constraints?.pinRight = false; - // } + if (context.contextConstraints.fixedWidth) { + node.constraints?.fixedWidth = context.contextConstraints.fixedWidth; + node.constraints?.pinLeft = true; + node.constraints?.pinRight = false; + } } } From 8a4d9ce62e5b561cd6f22045401267f195f9372f Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 25 Aug 2021 21:20:18 -0500 Subject: [PATCH 341/404] WIP switch order of assigning fixed widh and height and assigning context fixed width and height. --- .../helpers/align_strategy.dart | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 2058be64..53802656 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -24,14 +24,7 @@ abstract class AlignStrategy { /// assign the [node.constraints.pinTop] = `true` and [node.constraints.pinBottom] = `false`. /// When [context.fixedWidth] is not `null`, se assign the [context.fixedWidth] to subtree and /// we make [node.constraints.pinLeft] = `true` and [node.constraints.pingRight] = `false`. - void _setConstraints(PBContext context, T node) { - if(node.constraints.fixedHeight){ - context.contextConstraints.fixedHeight = true; - } - if(node.constraints.fixedWidth){ - context.contextConstraints.fixedWidth = true; - } - + void _setConstraints(PBContext context, T node) { if (context.contextConstraints.fixedHeight) { node.constraints?.fixedHeight = context.contextConstraints?.fixedHeight; node.constraints?.pinTop = true; @@ -43,6 +36,13 @@ abstract class AlignStrategy { node.constraints?.pinLeft = true; node.constraints?.pinRight = false; } + + if (node.constraints.fixedHeight) { + context.contextConstraints.fixedHeight = true; + } + if (node.constraints.fixedWidth) { + context.contextConstraints.fixedWidth = true; + } } } From 664553247ca0c18721f365ea972d5c6d48e622af Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Wed, 25 Aug 2021 22:03:18 -0600 Subject: [PATCH 342/404] WIP fixed the inherited constrains that are being passed down. --- .../subclasses/pb_intermediate_node.dart | 3 ++- .../helpers/align_strategy.dart | 8 ++++---- .../pb_alignment_generation_service.dart | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index bfbb39c3..19b85da8 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -162,7 +162,8 @@ abstract class PBIntermediateNode /// /// INFO: there might be a more straight fowards backtracking way of preventing these side effects. void align(PBContext context) { - alignStrategy.align(context, this); + // alignStrategy.setConstraints(context, this); + alignStrategy.align(context.clone(), this); for (var currChild in context.tree.childrenOf(this) ?? []) { currChild?.align(context.clone()); diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 53802656..6999b4df 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -24,7 +24,7 @@ abstract class AlignStrategy { /// assign the [node.constraints.pinTop] = `true` and [node.constraints.pinBottom] = `false`. /// When [context.fixedWidth] is not `null`, se assign the [context.fixedWidth] to subtree and /// we make [node.constraints.pinLeft] = `true` and [node.constraints.pingRight] = `false`. - void _setConstraints(PBContext context, T node) { + void setConstraints(PBContext context, T node) { if (context.contextConstraints.fixedHeight) { node.constraints?.fixedHeight = context.contextConstraints?.fixedHeight; node.constraints?.pinTop = true; @@ -62,14 +62,14 @@ class PaddingAlignment extends AlignStrategy { context.tree.addEdges(padding, [child]); context.tree.addEdges(node, [padding]); - super._setConstraints(context, node); + // super.setConstraints(context, node); } } class NoAlignment extends AlignStrategy { @override void align(PBContext context, PBIntermediateNode node) { - super._setConstraints(context, node); + // super.setConstraints(context, node); } } @@ -103,6 +103,6 @@ class PositionedAlignment extends AlignStrategy { tree.addEdges(injectedPositioned, [child]); }); tree.replaceChildrenOf(node, alignedChildren); - super._setConstraints(context, node); + // super.setConstraints(context, node); } } diff --git a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart index d2d1af89..3805d13a 100644 --- a/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart +++ b/lib/interpret_and_optimize/services/pb_alignment_generation_service.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/controllers/interpret.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -10,7 +11,6 @@ import 'package:quick_log/quick_log.dart'; /// Input: PBIntermediateNode Tree /// Output: PBIntermediateNode Tree class PBAlignGenerationService extends AITHandler { - /// Constructor for PBPluginGenerationService, must include the root SketchNode PBAlignGenerationService(); @@ -23,7 +23,22 @@ class PBAlignGenerationService extends AITHandler { '[PBAlignmentGenerationService] generate() attempted to generate a non-existing tree'); return null; } + tree.topologicalOrdering.forEach((element) { + if (element is PBIntermediateNode && + (element.parent?.constraints?.fixedHeight ?? false)) { + element.constraints.fixedHeight = true; + element.constraints.pinTop = true; + element.constraints.pinBottom = false; + } + if (element is PBIntermediateNode && + (element.parent?.constraints?.fixedWidth ?? false)) { + element.constraints.fixedWidth = true; + element.constraints.pinLeft = true; + element.constraints.pinRight = false; + } + }); tree.rootNode.align(context); + return Future.value(tree); } From 1c71a7c80daa7cc7168d85ce9c7c0c5b14d2f53f Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 26 Aug 2021 01:26:55 -0500 Subject: [PATCH 343/404] WIP generating different screen platforms for responsiveness. --- lib/controllers/interpret.dart | 3 +- lib/controllers/main_info.dart | 2 +- .../flutter_project_builder.dart | 5 +++ .../commands/add_constant_command.dart | 2 ++ .../pb_file_structure_strategy.dart | 8 ++++- .../pb_generation_configuration.dart | 3 +- .../entities/inherited_scaffold.dart | 20 +++++++---- ...b_platform_orientation_linker_service.dart | 36 +++++++++++-------- lib/main.dart | 2 ++ 9 files changed, 57 insertions(+), 24 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index c92a597b..772df76e 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -47,7 +47,8 @@ class Interpret { // PBPluginControlService(), PBLayoutGenerationService(), // PBConstraintGenerationService(), - PBAlignGenerationService() + PBAlignGenerationService(), + PBPlatformOrientationLinkerService(), ]; Future interpretAndOptimize( diff --git a/lib/controllers/main_info.dart b/lib/controllers/main_info.dart index 4d15ea01..5ec46b3c 100644 --- a/lib/controllers/main_info.dart +++ b/lib/controllers/main_info.dart @@ -117,6 +117,6 @@ enum DesignType { SKETCH, FIGMA, PBDL, UNKNOWN } class DummySentry { /// Decoupling the exception capture client from the services that report the [exception] void captureException({exception, stackTrace}) { - print('dummy sentry'); + print(''); } } diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index 14b992e5..0b21a511 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -139,6 +139,11 @@ class FlutterProjectBuilder { await formatProject(project.projectAbsPath, projectDir: MainInfo().outputPath); } + + void runCommandQueue() { + generationConfiguration.commandQueue + .forEach(generationConfiguration.fileStructureStrategy.commandCreated); + } } void WriteStyleClasses(String pathToFlutterProject) { diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index b8ac82c9..9a439145 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; @@ -21,6 +22,7 @@ class AddConstantCommand extends FileStructureCommand { _addConstant, p.join(strategy.GENERATED_PROJECT_PATH, CONST_DIR_PATH), CONST_FILE_NAME, + ownership: FileOwnership.DEV, ); } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart index 89b44f94..aa332535 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart @@ -238,7 +238,13 @@ abstract class FileStructureStrategy implements CommandInvoker { var modLines = modFile([]); var buffer = StringBuffer(); modLines.forEach(buffer.writeln); - writeDataToFile(buffer.toString(), directory, name, UUID: UUID); + writeDataToFile( + buffer.toString(), + directory, + name, + UUID: UUID, + ownership: ownership, + ); } } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index f7d0cd99..cadf33c4 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -138,7 +138,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { // fileStructureStrategy.dryRunMode = false; // commandQueue.forEach(fileStructureStrategy.commandCreated); - commandQueue.clear(); + // commandQueue.clear(); // await generateTrees(pb_project.forest, pb_project, context); } @@ -223,6 +223,7 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { platformsMap, screenName, fileStructureStrategy, rawImports); if (newCommand != null) { + newCommand.write(fileStructureStrategy); setMainForPlatform(newCommand, screenName); } }); diff --git a/lib/interpret_and_optimize/entities/inherited_scaffold.dart b/lib/interpret_and_optimize/entities/inherited_scaffold.dart index c1342da4..964cf4ba 100644 --- a/lib/interpret_and_optimize/entities/inherited_scaffold.dart +++ b/lib/interpret_and_optimize/entities/inherited_scaffold.dart @@ -69,10 +69,21 @@ class InheritedScaffold extends PBVisualIntermediateNode var appBar = getAttributeNamed(context.tree, 'appBar'); if (appBar != null) { context.canvasFrame = Rectangle3D( - context.screenFrame.left, + context.canvasFrame.left, appBar.frame.bottomRight.y, - context.screenFrame.width, - context.screenFrame.height - appBar.frame.height, + context.canvasFrame.width, + context.canvasFrame.height - appBar.frame.height, + 0, + ); + frame = context.canvasFrame; + } + var tabBar = getAttributeNamed(context.tree, 'bottomNavigationBar'); + if (tabBar != null) { + context.canvasFrame = Rectangle3D( + context.canvasFrame.left, + context.canvasFrame.top, + context.canvasFrame.width, + context.canvasFrame.height - tabBar.frame.height, 0, ); frame = context.canvasFrame; @@ -85,9 +96,6 @@ class InheritedScaffold extends PBVisualIntermediateNode ..parent = this; context.tree.addEdges(groupAtt, children.map((child) => child).toList()); - // Keep appbar and tabbar - var tabBar = getAttributeNamed(context.tree, 'bottomNavigationBar'); - context.tree.replaceChildrenOf(this, [groupAtt, appBar, tabBar]..removeWhere((element) => element == null)); } diff --git a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart index 37b16aca..58a4a43d 100644 --- a/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart +++ b/lib/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart @@ -1,4 +1,5 @@ import 'dart:collection'; +import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:recase/recase.dart'; import 'package:parabeac_core/controllers/main_info.dart'; @@ -9,7 +10,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_nod import 'dart:math'; import 'package:recase/recase.dart'; -class PBPlatformOrientationLinkerService { +class PBPlatformOrientationLinkerService extends AITHandler { static final PBPlatformOrientationLinkerService _pbPlatformLinkerService = PBPlatformOrientationLinkerService._internal(); @@ -31,11 +32,12 @@ class PBPlatformOrientationLinkerService { /// Populates [tree]'s platform and orientation information /// and adds [tree] to storage. - void addOrientationPlatformInformation(PBIntermediateTree tree, PBContext context) { + void addOrientationPlatformInformation( + PBIntermediateTree tree, PBContext context) { tree.generationViewData.platform = _extractPlatform(tree.name); tree.generationViewData.orientation = _extractOrientation( - tree.rootNode .frame.bottomRight, - tree.rootNode .frame.topLeft, + tree.rootNode.frame.bottomRight, + tree.rootNode.frame.topLeft, ); _platforms.add(tree.generationViewData.platform); @@ -44,15 +46,13 @@ class PBPlatformOrientationLinkerService { // Add orientation builder template to the project // if there are more than 1 orientation on the project if (hasMultipleOrientations()) { - context.configuration.generationConfiguration - .commandQueue + context.configuration.generationConfiguration.commandQueue .add(OrientationBuilderCommand(tree.UUID)); } // Add responsive layout builder template to the project // if there are more than 1 plataform on the project if (hasMultiplePlatforms()) { - context.configuration.generationConfiguration - .commandQueue + context.configuration.generationConfiguration.commandQueue .add(ResponsiveLayoutBuilderCommand(tree.UUID)); _addBreakpoints(tree, context); } @@ -71,8 +71,10 @@ class PBPlatformOrientationLinkerService { var treeName = key.snakeCase; var iterTreeName = currTree.rootNode.name.snakeCase; if (treeName == iterTreeName && - tree.generationViewData.orientation == currTree.generationViewData.orientation && - tree.generationViewData.platform == currTree.generationViewData.platform) { + tree.generationViewData.orientation == + currTree.generationViewData.orientation && + tree.generationViewData.platform == + currTree.generationViewData.platform) { // Rename the tree if both trees have the same orientation and platform tree.rootNode.name = treeName + '_${_mapCounter[iterTreeName]}'; _mapCounter[treeName]++; @@ -118,7 +120,8 @@ class PBPlatformOrientationLinkerService { for (var screen in screens) { // Add orientation to a platform if (result.containsKey(screen.generationViewData.platform)) { - result[screen.generationViewData.platform][screen.generationViewData.orientation] = screen; + result[screen.generationViewData.platform] + [screen.generationViewData.orientation] = screen; } // Create entry for current platform-orientation pair else { @@ -217,12 +220,17 @@ class PBPlatformOrientationLinkerService { bp.forEach((key, value) { var cmd = AddConstantCommand( tree.UUID, key + 'Breakpoint', 'num', value.toString()); - context.configuration.generationConfiguration - .commandQueue - .add(cmd); + context.configuration.generationConfiguration.commandQueue.add(cmd); }); } } + + @override + Future handleTree( + PBContext context, PBIntermediateTree tree) { + addOrientationPlatformInformation(tree, context); + return Future.value(tree); + } } /// Enum of supported platforms. diff --git a/lib/main.dart b/lib/main.dart index e50835f3..871fa8ca 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -144,6 +144,8 @@ ${parser.usage} await interpretService.interpretAndOptimize(tree, context, pbProject)); } + fpb.runCommandQueue(); + for (var tree in trees) { await fpb.genAITree(tree, tree.context, true); } From a3cccdbda8183eceebd881e901b8123cf9750041 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 26 Aug 2021 12:25:10 -0600 Subject: [PATCH 344/404] State management fix WIP --- lib/controllers/interpret.dart | 15 ------ .../middleware/command_gen_middleware.dart | 6 ++- .../commands/write_symbol_command.dart | 7 ++- .../helpers/pb_intermediate_node_tree.dart | 3 +- .../helpers/pb_state_management_linker.dart | 47 +++++++++++-------- 5 files changed, 37 insertions(+), 41 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index c92a597b..7c7e638b 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -1,31 +1,16 @@ -import 'dart:io'; -import 'dart:math'; import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; -import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; -import 'dart:convert'; -import 'package:parabeac_core/controllers/main_info.dart'; -import 'package:parabeac_core/generation/prototyping/pb_prototype_aggregation_service.dart'; import 'package:parabeac_core/generation/prototyping/pb_prototype_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/base_group.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_constraint_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; -import 'package:pbdl/pbdl.dart'; import 'package:quick_log/quick_log.dart'; import 'package:tuple/tuple.dart'; -import 'package:path/path.dart' as p; class Interpret { Logger log; diff --git a/lib/generation/generators/middleware/command_gen_middleware.dart b/lib/generation/generators/middleware/command_gen_middleware.dart index 9159f8a7..3dbd327e 100644 --- a/lib/generation/generators/middleware/command_gen_middleware.dart +++ b/lib/generation/generators/middleware/command_gen_middleware.dart @@ -28,7 +28,8 @@ class CommandGenMiddleware extends Middleware } @override - Future applyMiddleware(PBIntermediateTree tree, PBContext context) { + Future applyMiddleware( + PBIntermediateTree tree, PBContext context) { if (tree == null) { return Future.value(tree); } @@ -70,7 +71,8 @@ class CommandGenMiddleware extends Middleware /// If an import path is found, it will be added to the `tree`'s data. The package format /// for imports is going to be enforced, therefore, [packageName] is going to be /// a required parameter. - void _addDependencyImports(PBIntermediateTree tree, String packageName, PBContext context) { + void _addDependencyImports( + PBIntermediateTree tree, String packageName, PBContext context) { var iter = tree.dependentsOn; var addImport = context.managerData.addImport; diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index fb4282ea..9bfd7c65 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -20,7 +20,9 @@ class WriteSymbolCommand extends NodeFileStructureCommand { {this.relativePath = '', this.symbolPath = DEFAULT_SYMBOL_PATH, FileOwnership ownership = FileOwnership.PBC}) - : super(UUID, code, ownership); + : super(UUID, code, ownership) { + // print(''); + } /// Writes a symbol file containing [generationViewData] with [fileName] as its filename. /// @@ -31,7 +33,8 @@ class WriteSymbolCommand extends NodeFileStructureCommand { ? p.join(strategy.GENERATED_PROJECT_PATH, symbolPath) : p.join(strategy.GENERATED_PROJECT_PATH, symbolPath, relativePath); - strategy.writeDataToFile(code, absPath, fileName, UUID: UUID, ownership: ownership); + strategy.writeDataToFile(code, absPath, fileName, + UUID: UUID, ownership: ownership); return Future.value(p.join(absPath, fileName)); } } diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index b8fab820..67c64754 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -263,13 +263,12 @@ class PBIntermediateTree extends DirectedGraph { /// the [PBIntermediateNode]'s children are removed/added. abstract class ChildrenObserver { /// Even notification of [children] have been modified. - /// + /// /// [context] could be `null` when when the [PBIntermediateTree] is being initialized. [ChildrenObserver] /// can still modify the [children] but it would be unable to add/remove children. void childrenModified(List children, [PBContext context]); } - enum CHILDREN_MOD { CREATED, REMOVED, MODIFIED } typedef ChildrenModEventHandler = void Function( diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 5d8f8aea..881c0230 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -13,6 +13,7 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generati import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_state.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_variation.dart'; +import 'package:path/path.dart'; class PBStateManagementLinker { Interpret interpret; @@ -93,26 +94,32 @@ class PBStateManagementLinker { Future _interpretVariationNode( PBIntermediateNode node, PBIntermediateTree tree) async { var builder = AITServiceBuilder(); - builder - .addTransformation((PBIntermediateTree tree) { - var context = PBContext(MainInfo().configuration); - context.screenFrame = Rectangle3D.fromPoints( - tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); - - context.tree = tree; - tree.context = context; - - tree.forEach((element) => element.handleChildren(context)); - }) + tree.rootNode = node; + var tempContext = PBContext(MainInfo().configuration); + tempContext.screenFrame = Rectangle3D.fromPoints( + tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); + tempContext.tree = tree; + tree.context = tempContext; + + builder.addTransformation((PBContext context, PBIntermediateTree tree) { + tree.forEach((element) => element.handleChildren(context)); + + return tree; + }) // .addTransformation(visualGenerationService.getIntermediateTree) - .addTransformation((PBIntermediateTree tree, context) { - // / Making sure the name of the tree was changed back - tree.name = node.name; - }) - .addTransformation( - PBPluginControlService().convertAndModifyPluginNodeTree) - .addTransformation(PBLayoutGenerationService().extractLayouts) - .addTransformation(PBAlignGenerationService().addAlignmentToLayouts); - return builder.build(tree: tree).then((tree) => tree.rootNode); + .addTransformation((PBContext context, PBIntermediateTree tree) { + // / Making sure the name of the tree was changed back + tree.name = node.name; + return tree; + }).addTransformation((PBContext context, PBIntermediateTree tree) { + return PBPluginControlService() + .convertAndModifyPluginNodeTree(tree, context); + }).addTransformation((PBContext context, PBIntermediateTree tree) { + return PBLayoutGenerationService().extractLayouts(tree, context); + }).addTransformation((PBContext context, PBIntermediateTree tree) { + return PBAlignGenerationService().addAlignmentToLayouts(tree, context); + }); + await builder.build(tree: tree, context: tempContext); + return tree.rootNode; } } From 432e0aac0677d12187eb339b2145ca04fbd90893 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 26 Aug 2021 14:08:53 -0500 Subject: [PATCH 345/404] WIP generating code for state management variation files Created State Management Service AITHandler --- lib/controllers/interpret.dart | 4 ++- .../state_management/provider_middleware.dart | 4 +-- .../commands/write_symbol_command.dart | 4 +-- .../abstract_intermediate_node_factory.dart | 23 -------------- .../helpers/pb_state_management_linker.dart | 28 +++++++---------- .../state_management_node_interpreter.dart | 31 +++++++++++++++++++ .../state_management/intermediate_state.dart | 6 ++++ 7 files changed, 54 insertions(+), 46 deletions(-) create mode 100644 lib/interpret_and_optimize/services/state_management_node_interpreter.dart diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 7c7e638b..add1647a 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/state_management_node_interpreter.dart'; import 'package:quick_log/quick_log.dart'; import 'package:tuple/tuple.dart'; @@ -28,11 +29,12 @@ class Interpret { PBPrototypeLinkerService _pbPrototypeLinkerService; final List aitHandlers = [ + StateManagementNodeInterpreter(), PBSymbolLinkerService(), // PBPluginControlService(), PBLayoutGenerationService(), // PBConstraintGenerationService(), - PBAlignGenerationService() + PBAlignGenerationService(), ]; Future interpretAndOptimize( diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index da1b3663..99327df7 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -124,10 +124,10 @@ class ProviderMiddleware extends StateManagementMiddleware { // Generate node's states' view pages node.auxiliaryData?.stateGraph?.states?.forEach((state) { fileStrategy.commandCreated(WriteSymbolCommand( - context.tree.UUID, + state.context.tree.UUID, // state.variation.node.currentContext.tree.UUID, state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node, context), + generationManager.generate(state.variation.node, state.context), relativePath: parentDirectory, )); }); diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart index 9bfd7c65..42ebca2d 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart @@ -20,9 +20,7 @@ class WriteSymbolCommand extends NodeFileStructureCommand { {this.relativePath = '', this.symbolPath = DEFAULT_SYMBOL_PATH, FileOwnership ownership = FileOwnership.PBC}) - : super(UUID, code, ownership) { - // print(''); - } + : super(UUID, code, ownership); /// Writes a symbol file containing [generationViewData] with [fileName] as its filename. /// diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index 45af9c13..4efa0937 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -64,7 +64,6 @@ class AbstractIntermediateNodeFactory { return tag; } - interpretStateManagement(iNode, tree); if (parent != null && iNode != null) { tree.addEdges(parent, [iNode]); } @@ -75,28 +74,6 @@ class AbstractIntermediateNodeFactory { } return null; } - - /// Checks whether `node` is a state management node, and interprets it accordingly. - /// - /// Returns `null` if `node` is a non-default state management node, effectively removing `node` from the tree. - /// Returns `node` if it is a default state management node or a non-state management node. - static PBIntermediateNode interpretStateManagement( - PBIntermediateNode node, PBIntermediateTree tree) { - if (node is! PBSharedMasterNode) { - return node; - } - var smHelper = PBStateManagementHelper(); - if (smHelper.isValidStateNode(node.name)) { - if (smHelper.isDefaultNode(node)) { - smHelper.interpretStateManagementNode(node, tree); - return node; - } else { - smHelper.interpretStateManagementNode(node, tree); - return null; - } - } - return node; - } } abstract class IntermediateNodeFactory { diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 881c0230..2e0d01b4 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -63,8 +63,10 @@ class PBStateManagementLinker { // Add old default node as state of new default node stateQueue.add( _interpretVariationNode(instanceNode, tree).then((processedNode) { - var intermediateState = - IntermediateState(variation: IntermediateVariation(processedNode)); + var intermediateState = IntermediateState( + variation: IntermediateVariation(processedNode), + context: tree.context, + ); node.auxiliaryData.stateGraph.addState(intermediateState); })); @@ -79,8 +81,10 @@ class PBStateManagementLinker { tempSym?.forEach((element) => element.isMasterState = true); } stateQueue.add(_interpretVariationNode(node, tree).then((processedNode) { - var intermediateState = - IntermediateState(variation: IntermediateVariation(processedNode)); + var intermediateState = IntermediateState( + variation: IntermediateVariation(processedNode), + context: tree.context, + ); _statemap[rootNodeName] .auxiliaryData .stateGraph @@ -94,23 +98,13 @@ class PBStateManagementLinker { Future _interpretVariationNode( PBIntermediateNode node, PBIntermediateTree tree) async { var builder = AITServiceBuilder(); - tree.rootNode = node; - var tempContext = PBContext(MainInfo().configuration); - tempContext.screenFrame = Rectangle3D.fromPoints( - tree.rootNode.frame.topLeft, tree.rootNode.frame.bottomRight); - tempContext.tree = tree; - tree.context = tempContext; - builder.addTransformation((PBContext context, PBIntermediateTree tree) { - tree.forEach((element) => element.handleChildren(context)); - - return tree; - }) + builder // .addTransformation(visualGenerationService.getIntermediateTree) .addTransformation((PBContext context, PBIntermediateTree tree) { // / Making sure the name of the tree was changed back tree.name = node.name; - return tree; + return Future.value(tree); }).addTransformation((PBContext context, PBIntermediateTree tree) { return PBPluginControlService() .convertAndModifyPluginNodeTree(tree, context); @@ -119,7 +113,7 @@ class PBStateManagementLinker { }).addTransformation((PBContext context, PBIntermediateTree tree) { return PBAlignGenerationService().addAlignmentToLayouts(tree, context); }); - await builder.build(tree: tree, context: tempContext); + await builder.build(tree: tree, context: tree.context); return tree.rootNode; } } diff --git a/lib/interpret_and_optimize/services/state_management_node_interpreter.dart b/lib/interpret_and_optimize/services/state_management_node_interpreter.dart new file mode 100644 index 00000000..2a41d121 --- /dev/null +++ b/lib/interpret_and_optimize/services/state_management_node_interpreter.dart @@ -0,0 +1,31 @@ +import 'package:parabeac_core/controllers/interpret.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; + +class StateManagementNodeInterpreter extends AITHandler { + /// Checks whether `node` is a state management node, and interprets it accordingly. + /// + /// Returns `null` if `node` is a non-default state management node, effectively removing `node` from the tree. + /// Returns `node` if it is a default state management node or a non-state management node. + @override + Future handleTree( + PBContext context, PBIntermediateTree tree) { + if (tree.rootNode is! PBSharedMasterNode) { + return Future.value(tree); + } + var node = tree.rootNode; + var smHelper = PBStateManagementHelper(); + if (smHelper.isValidStateNode(node.name)) { + if (smHelper.isDefaultNode(node)) { + smHelper.interpretStateManagementNode(node, tree); + return Future.value(tree); + } else { + smHelper.interpretStateManagementNode(node, tree); + return Future.value(tree); + } + } + return Future.value(tree); + } +} diff --git a/lib/interpret_and_optimize/state_management/intermediate_state.dart b/lib/interpret_and_optimize/state_management/intermediate_state.dart index a18cbcd9..b7539b43 100644 --- a/lib/interpret_and_optimize/state_management/intermediate_state.dart +++ b/lib/interpret_and_optimize/state_management/intermediate_state.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_variation.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_vertex.dart'; @@ -6,9 +7,14 @@ class IntermediateState { List vertexes; bool isAppState; + /// Context is added in order for state to know how to generate + /// and inspect `variation's` children. + PBContext context; + IntermediateState({ this.variation, this.vertexes, this.isAppState, + this.context, }); } From 45c75d3caabd4798d55df92cb03c70042955b50d Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 26 Aug 2021 14:25:32 -0500 Subject: [PATCH 346/404] Removed unnecessary transformations from state management linker --- .../middleware/state_management/provider_middleware.dart | 1 - .../helpers/pb_state_management_linker.dart | 8 +------- .../services/state_management_node_interpreter.dart | 1 + 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 99327df7..a5b8bc4c 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -125,7 +125,6 @@ class ProviderMiddleware extends StateManagementMiddleware { node.auxiliaryData?.stateGraph?.states?.forEach((state) { fileStrategy.commandCreated(WriteSymbolCommand( state.context.tree.UUID, - // state.variation.node.currentContext.tree.UUID, state.variation.node.name.snakeCase, generationManager.generate(state.variation.node, state.context), relativePath: parentDirectory, diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 2e0d01b4..3f432641 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -99,13 +99,7 @@ class PBStateManagementLinker { PBIntermediateNode node, PBIntermediateTree tree) async { var builder = AITServiceBuilder(); - builder - // .addTransformation(visualGenerationService.getIntermediateTree) - .addTransformation((PBContext context, PBIntermediateTree tree) { - // / Making sure the name of the tree was changed back - tree.name = node.name; - return Future.value(tree); - }).addTransformation((PBContext context, PBIntermediateTree tree) { + builder.addTransformation((PBContext context, PBIntermediateTree tree) { return PBPluginControlService() .convertAndModifyPluginNodeTree(tree, context); }).addTransformation((PBContext context, PBIntermediateTree tree) { diff --git a/lib/interpret_and_optimize/services/state_management_node_interpreter.dart b/lib/interpret_and_optimize/services/state_management_node_interpreter.dart index 2a41d121..f6c14c83 100644 --- a/lib/interpret_and_optimize/services/state_management_node_interpreter.dart +++ b/lib/interpret_and_optimize/services/state_management_node_interpreter.dart @@ -22,6 +22,7 @@ class StateManagementNodeInterpreter extends AITHandler { smHelper.interpretStateManagementNode(node, tree); return Future.value(tree); } else { + /// Remove tree entirely smHelper.interpretStateManagementNode(node, tree); return Future.value(tree); } From 97b5a3b3bd700f2ca75a23cef21cccaee8139315 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 26 Aug 2021 15:49:32 -0600 Subject: [PATCH 347/404] Temporal fixes WIP --- .../services/state_management_node_interpreter.dart | 2 +- lib/main.dart | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/interpret_and_optimize/services/state_management_node_interpreter.dart b/lib/interpret_and_optimize/services/state_management_node_interpreter.dart index f6c14c83..491a15ca 100644 --- a/lib/interpret_and_optimize/services/state_management_node_interpreter.dart +++ b/lib/interpret_and_optimize/services/state_management_node_interpreter.dart @@ -24,7 +24,7 @@ class StateManagementNodeInterpreter extends AITHandler { } else { /// Remove tree entirely smHelper.interpretStateManagementNode(node, tree); - return Future.value(tree); + return Future.value(null); } } return Future.value(tree); diff --git a/lib/main.dart b/lib/main.dart index e50835f3..ee5836fe 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -140,8 +140,12 @@ ${parser.usage} tree.forEach((child) => child.handleChildren(context)); - trees.add( - await interpretService.interpretAndOptimize(tree, context, pbProject)); + var candidateTree = + await interpretService.interpretAndOptimize(tree, context, pbProject); + + if (candidateTree != null) { + trees.add(candidateTree); + } } for (var tree in trees) { From 4701587dd74797e6c03b7d842b493d07daf37f14 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 26 Aug 2021 17:56:12 -0500 Subject: [PATCH 348/404] Removed duplicate state management components --- lib/controllers/interpret.dart | 6 +++--- .../middleware/command_gen_middleware.dart | 7 +++++-- .../pb_generation_configuration.dart | 15 +-------------- .../helpers/pb_state_management_linker.dart | 6 ++---- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index add1647a..a962282c 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -143,14 +143,14 @@ class AITServiceBuilder { tree.replaceNode(child, dVertex); } } - } else if (transformation is AITTransformation) { + } else if (transformation is AITTransformation && _intermediateTree != null) { _intermediateTree = await transformation(context, _intermediateTree); } if (_intermediateTree == null || _intermediateTree.rootNode == null) { - log.error( + log.warning( 'The $name returned a null \"$treeName\" $PBIntermediateTree (or its rootnode is null)\n after its transformation, this will remove the tree from the process!'); - throw NullThrownError(); + // throw NullThrownError(); } } catch (e) { MainInfo().captureException(e); diff --git a/lib/generation/generators/middleware/command_gen_middleware.dart b/lib/generation/generators/middleware/command_gen_middleware.dart index 3dbd327e..c1675ba8 100644 --- a/lib/generation/generators/middleware/command_gen_middleware.dart +++ b/lib/generation/generators/middleware/command_gen_middleware.dart @@ -53,7 +53,8 @@ class CommandGenMiddleware extends Middleware tree.name, generationManager.generate(tree.rootNode, context), ); - } else { + } else if (tree.rootNode.auxiliaryData.stateGraph.states.isEmpty) { + // TODO: Find a more optimal way to exclude state management nodes command = WriteSymbolCommand( tree.UUID, tree.identifier, @@ -61,7 +62,9 @@ class CommandGenMiddleware extends Middleware relativePath: tree.name, ); } - configuration.fileStructureStrategy.commandCreated(command); + if (command != null) { + configuration.fileStructureStrategy.commandCreated(command); + } return Future.value(tree); } diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index f7d0cd99..9ec09d98 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -124,22 +124,9 @@ abstract class GenerationConfiguration with PBPlatformOrientationGeneration { ///First we are going to perform a dry run in the generation to ///gather all the necessary information await setUpConfiguration(pb_project); - - // fileStructureStrategy.dryRunMode = true; + fileStructureStrategy.addFileObserver(_importProcessor); - // pb_project.fileStructureStrategy = fileStructureStrategy; - - // pb_project.lockData = true; - // commandQueue.forEach(fileStructureStrategy.commandCreated); - // await generateTrees(pb_project.forest, pb_project, context); - // pb_project.lockData = false; - - ///After the dry run is complete, then we are able to create the actual files. - // fileStructureStrategy.dryRunMode = false; - - // commandQueue.forEach(fileStructureStrategy.commandCreated); commandQueue.clear(); - // await generateTrees(pb_project.forest, pb_project, context); } void registerMiddleware(Middleware middleware) { diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 3f432641..71c8ba18 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -1,7 +1,5 @@ -import 'dart:io'; import 'package:parabeac_core/controllers/interpret.dart'; -import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -11,9 +9,9 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.d import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_state.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_variation.dart'; -import 'package:path/path.dart'; class PBStateManagementLinker { Interpret interpret; @@ -97,7 +95,7 @@ class PBStateManagementLinker { /// the necessary interpretation services. Future _interpretVariationNode( PBIntermediateNode node, PBIntermediateTree tree) async { - var builder = AITServiceBuilder(); + var builder = AITServiceBuilder([PBSymbolLinkerService()]); builder.addTransformation((PBContext context, PBIntermediateTree tree) { return PBPluginControlService() From 0c88648e76d9ed5ce8b171a2a5a9dc57393164e3 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 26 Aug 2021 17:28:54 -0600 Subject: [PATCH 349/404] Changed provider models ownership to DEV --- .../middleware/state_management/provider_middleware.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index a5b8bc4c..713ef0e8 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; @@ -110,6 +111,7 @@ class ProviderMiddleware extends StateManagementMiddleware { parentDirectory, code, symbolPath: fileStrategy.RELATIVE_MODEL_PATH, + ownership: FileOwnership.DEV, ), // Generate default node's view page WriteSymbolCommand(context.tree.UUID, node.name.snakeCase, From e07592f8f3bb7d15f4210d031bcea17c8d51614c Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 26 Aug 2021 20:46:11 -0600 Subject: [PATCH 350/404] WIP CREATED InjectedCenter to center elements. --- .../visual-widgets/pb_center_gen.dart | 19 +++++++++++++++++++ .../entities/alignments/injected_center.dart | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 lib/generation/generators/visual-widgets/pb_center_gen.dart create mode 100644 lib/interpret_and_optimize/entities/alignments/injected_center.dart diff --git a/lib/generation/generators/visual-widgets/pb_center_gen.dart b/lib/generation/generators/visual-widgets/pb_center_gen.dart new file mode 100644 index 00000000..7673e007 --- /dev/null +++ b/lib/generation/generators/visual-widgets/pb_center_gen.dart @@ -0,0 +1,19 @@ +import 'package:parabeac_core/generation/generators/pb_generator.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_center.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; + +class PBCenterGenerator extends PBGenerator { + @override + String generate(PBIntermediateNode source, PBContext context) { + var children = context.tree.childrenOf(source); + if (!(source is InjectedCenter) || children.isEmpty) { + return ''; + } + if (children.length > 1) { + logger.error( + '$runtimeType contains more than a single child. Rendering only the first one'); + } + return 'Center(\nchild: ${children.first.generator.generate(children.first, context)})'; + } +} diff --git a/lib/interpret_and_optimize/entities/alignments/injected_center.dart b/lib/interpret_and_optimize/entities/alignments/injected_center.dart new file mode 100644 index 00000000..bad4b000 --- /dev/null +++ b/lib/interpret_and_optimize/entities/alignments/injected_center.dart @@ -0,0 +1,18 @@ +import 'package:parabeac_core/generation/generators/visual-widgets/pb_center_gen.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; + +/// Represents the Center widget used in flutter to center its elements within +class InjectedCenter extends PBIntermediateNode + implements PBInjectedIntermediate { + InjectedCenter(String UUID, Rectangle3D frame, String name, + {PBIntermediateConstraints constraints}) + : super(UUID, frame, name, constraints: constraints) { + generator = PBCenterGenerator(); + childrenStrategy = OneChildStrategy('child'); + alignStrategy = NoAlignment(); + } +} From 1b9648aaeb862df1a7332ef490be0586d2f42d2a Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 26 Aug 2021 22:21:50 -0500 Subject: [PATCH 351/404] remove rule not adding positioneds to elements that take up the stack --- lib/interpret_and_optimize/helpers/align_strategy.dart | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 6999b4df..fcaa5bea 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -81,15 +81,7 @@ class PositionedAlignment extends AlignStrategy { var alignedChildren = []; var tree = context.tree; var nodeChildren = context.tree.childrenOf(node); - nodeChildren.skipWhile((child) { - /// if they are the same size then there is no need for adjusting. - if (child.frame.topLeft == node.frame.topLeft && - child.frame.bottomRight == node.frame.bottomRight) { - alignedChildren.add(child); - return true; - } - return false; - }).forEach((child) { + nodeChildren.forEach((child) { var injectedPositioned = InjectedPositioned(null, child.frame, constraints: child.constraints, valueHolder: PositionedValueHolder( From de284d8df2e4837111b5fa9d0c15581a8361848a Mon Sep 17 00:00:00 2001 From: Eddie Herrera Date: Thu, 26 Aug 2021 21:36:58 -0600 Subject: [PATCH 352/404] WIP ADDED the center under the position --- .../visual-widgets/pb_container_gen.dart | 64 ++++++++++++------- .../entities/alignments/injected_center.dart | 2 +- .../entities/injected_container.dart | 27 ++++---- .../subclasses/pb_intermediate_node.dart | 2 +- .../helpers/align_strategy.dart | 32 +++++++++- 5 files changed, 88 insertions(+), 39 deletions(-) diff --git a/lib/generation/generators/visual-widgets/pb_container_gen.dart b/lib/generation/generators/visual-widgets/pb_container_gen.dart index 603364d5..ad1825c3 100644 --- a/lib/generation/generators/visual-widgets/pb_container_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_container_gen.dart @@ -2,6 +2,8 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_box_deco import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'dart:math'; @@ -13,32 +15,48 @@ class PBContainerGenerator extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext context) { - var sourceChildren = context.tree.childrenOf(source); - var buffer = StringBuffer(); - buffer.write('Container('); + if (source is InjectedContainer || source is InheritedContainer) { + var sourceChildren = context.tree.childrenOf(source); + var buffer = StringBuffer(); + buffer.write('Container('); - buffer.write(PBSizeHelper().generate(source, context)); + //TODO(ivanV): please clean my if statement :( + if (source is InjectedContainer) { + if (source.pointValueHeight) { + buffer.write('height: ${source.frame.height},'); + } + if (source.pointValueWidth) { + buffer.write('width: ${source.frame.width},'); + } + if (!source.pointValueHeight && !source.pointValueWidth) { + buffer.write(PBSizeHelper().generate(source, context)); + } + }else { + buffer.write(PBSizeHelper().generate(source, context)); + } - if (source.auxiliaryData.borderInfo != null) { - buffer.write(PBBoxDecorationHelper().generate(source, context)); - } else { - buffer.write(PBColorGenHelper().generate(source, context)); - } + if (source.auxiliaryData.borderInfo != null) { + buffer.write(PBBoxDecorationHelper().generate(source, context)); + } else { + buffer.write(PBColorGenHelper().generate(source, context)); + } - // if (source.auxiliaryData.alignment != null) { - // buffer.write( - // 'alignment: Alignment(${(source.auxiliaryData.alignment['alignX'] as double).toStringAsFixed(2)}, ${(source.auxiliaryData.alignment['alignY'] as double).toStringAsFixed(2)}),'); - // } - var child = sourceChildren.isEmpty ? null : sourceChildren.first; - if (child != null) { - child.frame = source.frame; - // source.child.currentContext = source.currentContext; - var statement = child != null - ? 'child: ${child.generator.generate(child, context)}' - : ''; - buffer.write(statement); + // if (source.auxiliaryData.alignment != null) { + // buffer.write( + // 'alignment: Alignment(${(source.auxiliaryData.alignment['alignX'] as double).toStringAsFixed(2)}, ${(source.auxiliaryData.alignment['alignY'] as double).toStringAsFixed(2)}),'); + // } + var child = sourceChildren.isEmpty ? null : sourceChildren.first; + if (child != null) { + child.frame = source.frame; + // source.child.currentContext = source.currentContext; + var statement = child != null + ? 'child: ${child.generator.generate(child, context)}' + : ''; + buffer.write(statement); + } + buffer.write(')'); + return buffer.toString(); } - buffer.write(')'); - return buffer.toString(); + return ''; } } diff --git a/lib/interpret_and_optimize/entities/alignments/injected_center.dart b/lib/interpret_and_optimize/entities/alignments/injected_center.dart index bad4b000..fc13eb2c 100644 --- a/lib/interpret_and_optimize/entities/alignments/injected_center.dart +++ b/lib/interpret_and_optimize/entities/alignments/injected_center.dart @@ -9,7 +9,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart class InjectedCenter extends PBIntermediateNode implements PBInjectedIntermediate { InjectedCenter(String UUID, Rectangle3D frame, String name, - {PBIntermediateConstraints constraints}) + {PBIntermediateConstraints constraints, }) : super(UUID, frame, name, constraints: constraints) { generator = PBCenterGenerator(); childrenStrategy = OneChildStrategy('child'); diff --git a/lib/interpret_and_optimize/entities/injected_container.dart b/lib/interpret_and_optimize/entities/injected_container.dart index eb2d093a..462d26a4 100644 --- a/lib/interpret_and_optimize/entities/injected_container.dart +++ b/lib/interpret_and_optimize/entities/injected_container.dart @@ -34,17 +34,20 @@ class InjectedContainer extends PBVisualIntermediateNode @JsonKey() String type = 'injected_container'; - InjectedContainer( - UUID, - Rectangle3D frame, { - String name, - double alignX, - double alignY, - String color, - this.prototypeNode, - this.type, - PBIntermediateConstraints constraints - }) : super( + bool pointValueWidth; + bool pointValueHeight; + + InjectedContainer(UUID, Rectangle3D frame, + {String name, + double alignX, + double alignY, + String color, + this.prototypeNode, + this.type, + this.pointValueHeight = false, + this.pointValueWidth = false, + PBIntermediateConstraints constraints}) + : super( UUID, frame, name, @@ -58,6 +61,6 @@ class InjectedContainer extends PBVisualIntermediateNode @override PBIntermediateNode createIntermediateNode(Map json, - PBIntermediateNode parent, PBIntermediateTree tree) => + PBIntermediateNode parent, PBIntermediateTree tree) => InjectedContainer.fromJson(json); } diff --git a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart index 19b85da8..44507228 100644 --- a/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart +++ b/lib/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart @@ -80,7 +80,7 @@ abstract class PBIntermediateNode super(null) { logger = Logger(runtimeType.toString()); if (_UUID == null) { - logger.warning( + logger.debug( 'Generating UUID for $runtimeType-$name as its UUID is null'); _UUID = Uuid().v4(); } diff --git a/lib/interpret_and_optimize/helpers/align_strategy.dart b/lib/interpret_and_optimize/helpers/align_strategy.dart index 6999b4df..1634e6d3 100644 --- a/lib/interpret_and_optimize/helpers/align_strategy.dart +++ b/lib/interpret_and_optimize/helpers/align_strategy.dart @@ -1,6 +1,8 @@ import 'package:directed_graph/directed_graph.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_center.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/injected_positioned.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/alignments/padding.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -90,8 +92,10 @@ class PositionedAlignment extends AlignStrategy { } return false; }).forEach((child) { + var centerY = false; + var centerX = false; var injectedPositioned = InjectedPositioned(null, child.frame, - constraints: child.constraints, + constraints: child.constraints.clone(), valueHolder: PositionedValueHolder( top: child.frame.topLeft.y - node.frame.topLeft.y, bottom: node.frame.bottomRight.y - child.frame.bottomRight.y, @@ -99,8 +103,32 @@ class PositionedAlignment extends AlignStrategy { right: node.frame.bottomRight.x - child.frame.bottomRight.x, width: child.frame.width, height: child.frame.height)); + if ((!child.constraints.pinLeft && !child.constraints.pinRight) && + child.constraints.fixedWidth) { + injectedPositioned.constraints.fixedWidth = false; + centerX = true; + } + if ((!child.constraints.pinTop && !child.constraints.pinBottom) && + child.constraints.fixedHeight) { + injectedPositioned.constraints.fixedHeight = false; + centerY = true; + } alignedChildren.add(injectedPositioned); - tree.addEdges(injectedPositioned, [child]); + if (!(centerX || centerY)) { + /// we are no center, since there is no need in either axis + tree.addEdges(injectedPositioned, [child]); + } else { + var center = InjectedCenter(null, child.frame.boundingBox(child.frame), + '$InjectedCenter-${child.name}'); + + /// The container is going to be used to control the point value height/width + var container = InjectedContainer( + null, child.frame.boundingBox(child.frame), + pointValueHeight: centerY, pointValueWidth: centerX); + tree.addEdges(container, [child]); + tree.addEdges(center, [container]); + tree.addEdges(injectedPositioned, [center]); + } }); tree.replaceChildrenOf(node, alignedChildren); // super.setConstraints(context, node); From 28f42ed210f95c0bcb2ed3d658f887bbc7201d3b Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 13 Aug 2021 12:42:22 -0600 Subject: [PATCH 353/404] Added JSON to PBDL --- lib/controllers/main_info.dart | 2 +- .../design_to_pbdl/figma_to_pbdl_service.dart | 13 ++++++++----- .../design_to_pbdl/json_to_pbdl_service.dart | 17 +++++++++++++++++ .../design_to_pbdl/sketch_to_pbdl_service.dart | 1 + lib/main.dart | 4 +++- 5 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 lib/interpret_and_optimize/services/design_to_pbdl/json_to_pbdl_service.dart diff --git a/lib/controllers/main_info.dart b/lib/controllers/main_info.dart index 4d15ea01..5c2e4c96 100644 --- a/lib/controllers/main_info.dart +++ b/lib/controllers/main_info.dart @@ -75,7 +75,7 @@ class MainInfo { /// Exporting the PBDL JSON file instead of generating the actual Flutter code. bool exportPBDL; - Map pbdf; + Map pbdl; /// Type of [DesignType] that is being processed by the current process of /// Parabeac Core. diff --git a/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart b/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart index 58e26434..0db0726e 100644 --- a/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart +++ b/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart @@ -8,9 +8,12 @@ class FigmaToPBDLService implements DesignToPBDLService { DesignType designType = DesignType.FIGMA; @override - Future callPBDL(MainInfo info) => PBDL.fromFigma( - info.figmaProjectID, - info.figmaKey, - outputPath: p.join(info.genProjectPath, 'assets'), - ); + Future callPBDL(MainInfo info) { + return PBDL.fromFigma( + info.figmaProjectID, + info.figmaKey, + outputPath: p.join(info.genProjectPath, 'assets'), + exportPbdlJson: info.exportPBDL, + ); + } } diff --git a/lib/interpret_and_optimize/services/design_to_pbdl/json_to_pbdl_service.dart b/lib/interpret_and_optimize/services/design_to_pbdl/json_to_pbdl_service.dart new file mode 100644 index 00000000..33f41b37 --- /dev/null +++ b/lib/interpret_and_optimize/services/design_to_pbdl/json_to_pbdl_service.dart @@ -0,0 +1,17 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart'; +import 'package:pbdl/pbdl.dart'; +import 'package:path/path.dart' as p; + +class JsonToPBDLService implements DesignToPBDLService { + @override + Future callPBDL(MainInfo info) async { + var pbdlJson = jsonDecode(File(MainInfo().pbdlPath).readAsStringSync()); + return await PBDL.fromJson(pbdlJson); + } + + @override + DesignType designType = DesignType.PBDL; +} diff --git a/lib/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart b/lib/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart index dda30f3b..faa32e0d 100644 --- a/lib/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart +++ b/lib/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart @@ -9,6 +9,7 @@ class SketchToPBDLService implements DesignToPBDLService { return PBDL.fromSketch( info.designFilePath, outputPath: p.join(info.genProjectPath, 'assets'), + exportPbdlJson: info.exportPBDL, ); } diff --git a/lib/main.dart b/lib/main.dart index e50835f3..834c00ba 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -14,6 +14,7 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_plugin_list_help import 'package:parabeac_core/interpret_and_optimize/helpers/pb_project.dart'; import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/design_to_pbdl_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/json_to_pbdl_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/design_to_pbdl/sketch_to_pbdl_service.dart'; import 'package:quick_log/quick_log.dart'; import 'package:uuid/uuid.dart'; @@ -27,6 +28,7 @@ import 'package:path/path.dart' as p; import 'interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; final designToPBDLServices = [ + JsonToPBDLService(), SketchToPBDLService(), FigmaToPBDLService(), ]; @@ -296,7 +298,7 @@ bool hasTooManyArgs(ArgResults args) { var hasAll = hasSketch && hasFigma && hasPbdl; - return hasAll || !(hasSketch ^ hasFigma /*^ hasPbdl*/); + return hasAll || !(hasSketch ^ hasFigma ^ hasPbdl); } /// Returns true if `args` does not contain any intake From 9bc03c995f09ccfd557fd22e2d0301a2c3584073 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 13 Aug 2021 12:42:22 -0600 Subject: [PATCH 354/404] Added JSON to PBDL --- .../helpers/pb_intermediate_node_tree.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index b8fab820..e6128524 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -44,6 +44,9 @@ class PBIntermediateTree extends DirectedGraph { @JsonKey(ignore: true) bool lockData = false; + @JsonKey(defaultValue: true) + bool convert; + PBGenerationViewData _generationViewData; @JsonKey(ignore: true) PBGenerationViewData get generationViewData => _generationViewData; @@ -263,13 +266,12 @@ class PBIntermediateTree extends DirectedGraph { /// the [PBIntermediateNode]'s children are removed/added. abstract class ChildrenObserver { /// Even notification of [children] have been modified. - /// + /// /// [context] could be `null` when when the [PBIntermediateTree] is being initialized. [ChildrenObserver] /// can still modify the [children] but it would be unable to add/remove children. void childrenModified(List children, [PBContext context]); } - enum CHILDREN_MOD { CREATED, REMOVED, MODIFIED } typedef ChildrenModEventHandler = void Function( From 41319514ebe3d932a0c616acffc6f713ae859adf Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sun, 29 Aug 2021 21:39:20 -0500 Subject: [PATCH 355/404] Call `fromFigma()` with projectName attribute set Point PBDL to `master` branch --- .../helpers/pb_intermediate_node_tree.g.dart | 3 ++- .../services/design_to_pbdl/figma_to_pbdl_service.dart | 1 + pbdl | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart index af205e40..3f596109 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.g.dart @@ -9,10 +9,11 @@ part of 'pb_intermediate_node_tree.dart'; PBIntermediateTree _$PBIntermediateTreeFromJson(Map json) { return PBIntermediateTree( name: json['name'] as String, - ); + )..convert = json['convert'] as bool ?? true; } Map _$PBIntermediateTreeToJson(PBIntermediateTree instance) => { + 'convert': instance.convert, 'name': instance.name, }; diff --git a/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart b/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart index 0db0726e..64d97b35 100644 --- a/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart +++ b/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart @@ -14,6 +14,7 @@ class FigmaToPBDLService implements DesignToPBDLService { info.figmaKey, outputPath: p.join(info.genProjectPath, 'assets'), exportPbdlJson: info.exportPBDL, + projectName: info.projectName, ); } } diff --git a/pbdl b/pbdl index 51d3084a..17933d18 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 51d3084ae4a2cca8f71a31fba144859e73ddbee5 +Subproject commit 17933d189622c3d99a29f5f9dae6dac7d08fe471 From 35e82b22db3951fa0b79dd2128c3ef9ef4c12f47 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sun, 29 Aug 2021 22:51:03 -0500 Subject: [PATCH 356/404] Update PBDL ref --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index 17933d18..e48cb9ee 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 17933d189622c3d99a29f5f9dae6dac7d08fe471 +Subproject commit e48cb9eed04d233a886bb17955f5f5de1d6c3348 From 36b0a5df879761a5bf0f343bc749d0edf218e6f1 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sun, 29 Aug 2021 23:14:58 -0500 Subject: [PATCH 357/404] Remove InjectedBackArrow temporarily due to issues --- lib/eggs/injected_back_arrow.dart | 53 ------------------------------- 1 file changed, 53 deletions(-) delete mode 100644 lib/eggs/injected_back_arrow.dart diff --git a/lib/eggs/injected_back_arrow.dart b/lib/eggs/injected_back_arrow.dart deleted file mode 100644 index a00179e6..00000000 --- a/lib/eggs/injected_back_arrow.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:parabeac_core/generation/generators/pb_generator.dart'; -import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; - -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; - -class InjectedBackArrow extends PBEgg implements PBInjectedIntermediate { - @override - String semanticName = ''; - - @override - ChildrenStrategy childrenStrategy = NoChildStrategy(); - - @override - AlignStrategy alignStrategy = NoAlignment(); - - InjectedBackArrow( - String UUID, - Rectangle3D frame, - String name, - ) : super(UUID, frame, name) { - generator = PBBackArrowGenerator(); - } - - @override - void extractInformation(PBIntermediateNode incomingNode) {} - - @override - PBEgg generatePluginNode(Rectangle3D frame, PBIntermediateNode originalRef, - PBIntermediateTree tree) { - return InjectedBackArrow( - UUID, - frame, - originalRef.name, - ); - } -} - -class PBBackArrowGenerator extends PBGenerator { - PBBackArrowGenerator() : super(); - - @override - String generate(PBIntermediateNode source, PBContext generatorContext) { - if (source is InjectedBackArrow) { - return 'BackButton()'; - } - } -} From a1d861c59c5f9635113dc8d305805e333e5a2d42 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Mon, 30 Aug 2021 14:22:18 -0500 Subject: [PATCH 358/404] Add prototyping toggle to configurations.json This will be disabled by default --- lib/configurations/configurations.json | 29 +++++++++---------- lib/controllers/interpret.dart | 7 ++++- .../entities/injected_container.g.dart | 4 +++ .../helpers/pb_configuration.dart | 15 ++++++++-- .../helpers/pb_configuration.g.dart | 2 ++ 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index c153b392..fe22caab 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -1,17 +1,14 @@ { - "widgetStyle": "Material", - "widgetType": "Stateless", - "widgetSpacing": "Expanded", - "layoutPrecedence": [ - "column", - "row", - "stack" - ], - "state-management": "provider", - "breakpoints": { - "mobile": 360, - "tablet": 600, - "desktop": 1280 - }, - "scaling": true -} \ No newline at end of file + "widgetStyle": "Material", + "widgetType": "Stateless", + "widgetSpacing": "Expanded", + "layoutPrecedence": ["column", "row", "stack"], + "state-management": "provider", + "breakpoints": { + "mobile": 360, + "tablet": 600, + "desktop": 1280 + }, + "scaling": true, + "enablePrototyping": false +} diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 772df76e..17f56bf0 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -77,7 +77,12 @@ class Interpret { return Future.value(tree); }, index: 1, id: 'Removing the $BaseGroup from ${tree.name}'); - await _pbPrototypeLinkerService.linkPrototypeNodes(tree, context); + // TODO: We should dynamically add the [PBPrototypeLinkerService] to `aitHandlers` + // somewhere else so that it does not check the configuration every time + // we process a tree + if (MainInfo().configuration.enablePrototyping) { + await _pbPrototypeLinkerService.linkPrototypeNodes(tree, context); + } // await PBPrototypeAggregationService().linkDanglingPrototypeNodes(); return aitServiceBuilder.build(tree: tree, context: context); diff --git a/lib/interpret_and_optimize/entities/injected_container.g.dart b/lib/interpret_and_optimize/entities/injected_container.g.dart index 8e69d5cf..b5ed0bd4 100644 --- a/lib/interpret_and_optimize/entities/injected_container.g.dart +++ b/lib/interpret_and_optimize/entities/injected_container.g.dart @@ -14,6 +14,8 @@ InjectedContainer _$InjectedContainerFromJson(Map json) { prototypeNode: PrototypeNode.prototypeNodeFromJson(json['prototypeNode'] as String), type: json['type'] as String, + pointValueHeight: json['pointValueHeight'] as bool, + pointValueWidth: json['pointValueWidth'] as bool, constraints: json['constraints'] == null ? null : PBIntermediateConstraints.fromJson( @@ -36,4 +38,6 @@ Map _$InjectedContainerToJson(InjectedContainer instance) => 'name': instance.name, 'prototypeNode': instance.prototypeNode, 'type': instance.type, + 'pointValueWidth': instance.pointValueWidth, + 'pointValueHeight': instance.pointValueHeight, }; diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.dart b/lib/interpret_and_optimize/helpers/pb_configuration.dart index dcfeada1..00180a39 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.dart @@ -49,8 +49,19 @@ class PBConfiguration { @JsonKey(name: 'breakpoints') final Map breakpoints; - PBConfiguration(this.widgetStyle, this.widgetType, this.widgetSpacing, - this.stateManagement, this.layoutPrecedence, this.breakpoints, this.scaling); + @JsonKey(defaultValue: false) + final bool enablePrototyping; + + PBConfiguration( + this.widgetStyle, + this.widgetType, + this.widgetSpacing, + this.stateManagement, + this.layoutPrecedence, + this.breakpoints, + this.scaling, + this.enablePrototyping, + ); /// Converting the [json] into a [PBConfiguration] object. /// diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart index 54c70319..a0954c97 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart @@ -16,6 +16,7 @@ PBConfiguration _$PBConfigurationFromJson(Map json) { ['column', 'row', 'stack'], json['breakpoints'] as Map, json['scaling'] as bool ?? true, + json['enablePrototyping'] as bool ?? false, ); } @@ -28,4 +29,5 @@ Map _$PBConfigurationToJson(PBConfiguration instance) => 'state-management': instance.stateManagement, 'layoutPrecedence': instance.layoutPrecedence, 'breakpoints': instance.breakpoints, + 'enablePrototyping': instance.enablePrototyping, }; From f1398c6aac05441e48363a7befb4d363347cec43 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Mon, 30 Aug 2021 14:29:14 -0500 Subject: [PATCH 359/404] Fix incorrect constraints for texts --- lib/interpret_and_optimize/entities/inherited_text.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/interpret_and_optimize/entities/inherited_text.dart b/lib/interpret_and_optimize/entities/inherited_text.dart index ceaeb152..d9647d76 100644 --- a/lib/interpret_and_optimize/entities/inherited_text.dart +++ b/lib/interpret_and_optimize/entities/inherited_text.dart @@ -113,6 +113,7 @@ class InheritedText extends PBVisualIntermediateNode // bottomRightCorner: inheritedText .frame.bottomRight, name: inheritedText.name, originalRef: json, + constraints: inheritedText.constraints, )..attributeName = inheritedText.attributeName; tree.addEdges(container, [inheritedText]); From 05facbbeae95bc7b9d74718e3a40fe41940bde09 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 30 Aug 2021 18:41:19 -0600 Subject: [PATCH 360/404] Added context to middleware body creation --- .../utils/middleware_utils.dart | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 738c7260..2812e273 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -1,4 +1,3 @@ - import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -6,12 +5,8 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:recase/recase.dart'; class MiddlewareUtils { - static String generateChangeNotifierClass( - String defaultStateName, - PBGenerationManager manager, - PBIntermediateNode node, - PBContext context - ) { + static String generateChangeNotifierClass(String defaultStateName, + PBGenerationManager manager, PBIntermediateNode node, PBContext context) { var overrideVars = ''; // Variables outside of initializer var overrideAttr = ''; // Attributes that will be part of initializer var stateInitializers = StringBuffer(); @@ -25,9 +20,9 @@ class MiddlewareUtils { }); stateBuffer.write(MiddlewareUtils.generateEmptyVariable(node)); stateInitializers.write( - '${node.name.camelCase} = ${MiddlewareUtils.generateVariableBody(node)}'); + '${node.name.camelCase} = ${MiddlewareUtils.generateVariableBody(node, context)}'); } else { - stateBuffer.write(MiddlewareUtils.generateVariable(node)); + stateBuffer.write(MiddlewareUtils.generateVariable(node, context)); } node?.auxiliaryData?.stateGraph?.states?.forEach((state) { context.tree.generationViewData = context.managerData; @@ -42,9 +37,10 @@ class MiddlewareUtils { }); stateBuffer.write(MiddlewareUtils.generateEmptyVariable(variationNode)); stateInitializers.write( - '${variationNode.name.camelCase} = ${MiddlewareUtils.generateVariableBody(variationNode)}'); + '${variationNode.name.camelCase} = ${MiddlewareUtils.generateVariableBody(variationNode, context)}'); } else { - stateBuffer.writeln(MiddlewareUtils.generateVariable(variationNode)); + stateBuffer + .writeln(MiddlewareUtils.generateVariable(variationNode, context)); } }); @@ -65,12 +61,8 @@ class MiddlewareUtils { '''; } - static String generateModelChangeNotifier( - String defaultStateName, - PBGenerationManager manager, - PBIntermediateNode node, - PBContext context - ) { + static String generateModelChangeNotifier(String defaultStateName, + PBGenerationManager manager, PBIntermediateNode node, PBContext context) { // Pass down manager data to states node?.auxiliaryData?.stateGraph?.states?.forEach((state) { // context.tree = node.managerData; @@ -93,18 +85,19 @@ class MiddlewareUtils { '''; } - static String generateVariable(PBIntermediateNode node, + static String generateVariable(PBIntermediateNode node, PBContext context, {String type = 'var'}) { - return '$type ${node.name.camelCase} = ${generateVariableBody(node)};'; + return '$type ${node.name.camelCase} = ${generateVariableBody(node, context)};'; } static String generateEmptyVariable(PBIntermediateNode node, {String type = 'var'}) => '$type ${node.name.camelCase};'; - static String generateVariableBody(PBIntermediateNode node) { - // node.currentContext.sizingContext = SizingValueContext.PointValue; - // return (node?.generator?.generate(node ?? '', node.currentContext) ?? ''); + static String generateVariableBody( + PBIntermediateNode node, PBContext context) { + context.sizingContext = SizingValueContext.PointValue; + return (node?.generator?.generate(node ?? '', context) ?? ''); } static String wrapOnLayout(String className) { From e980cf0ebe35f139466aaf8ae77eca92f1564582 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 30 Aug 2021 18:41:40 -0600 Subject: [PATCH 361/404] Fixes with .g for middlewares --- .../state_management/bloc_middleware.dart | 65 ++++++++++--------- .../state_management/provider_middleware.dart | 2 +- .../state_management/riverpod_middleware.dart | 6 +- .../commands/add_constant_command.dart | 2 +- .../bloc_state_template_strategy.dart | 4 +- 5 files changed, 44 insertions(+), 35 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 030fd7d0..ae570c3d 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -61,7 +62,8 @@ class BLoCMiddleware extends StateManagementMiddleware { } @override - Future handleStatefulNode(PBIntermediateNode node, PBContext context) { + Future handleStatefulNode( + PBIntermediateNode node, PBContext context) { // var managerData = node.managerData; context.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); @@ -73,7 +75,8 @@ class BLoCMiddleware extends StateManagementMiddleware { if (node is PBSharedInstanceIntermediateNode) { var generalStateName = node.functionCallName .substring(0, node.functionCallName.lastIndexOf('/')); - context.managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); + context.managerData + .addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); if (node.generator is! StringGeneratorAdapter) { var nameWithCubit = '${generalStateName.pascalCase}Cubit'; var nameWithState = '${generalStateName.pascalCase}State'; @@ -133,28 +136,31 @@ class BLoCMiddleware extends StateManagementMiddleware { /// Creates state page fileStrategy.commandCreated(WriteSymbolCommand( - - /// modified the [UUID] to prevent adding import because the state is - /// using `part of` syntax already when importing the bloc - 'STATE${context.tree.UUID}', - '${generalName}_state', - stateBuffer.toString(), - symbolPath: blocDirectory,)); + /// modified the [UUID] to prevent adding import because the state is + /// using `part of` syntax already when importing the bloc + 'STATE${context.tree.UUID}', + '${generalName}_state', + stateBuffer.toString(), + symbolPath: blocDirectory, + ownership: FileOwnership.DEV, + )); /// Creates map page mapBuffer.write(_makeStateToWidgetFunction(node)); fileStrategy.commandCreated(WriteSymbolCommand( - - /// modified the [UUID] to prevent adding import because the event is - /// using `part of` syntax already when importing the bloc - '${context.tree.UUID}', - '${generalName}_map', - mapBuffer.toString(), - symbolPath: blocDirectory)); + /// modified the [UUID] to prevent adding import because the event is + /// using `part of` syntax already when importing the bloc + '${context.tree.UUID}', + '${generalName}_map', + mapBuffer.toString(), + symbolPath: blocDirectory, + ownership: FileOwnership.DEV, + )); // Generate node's states' view pages node.auxiliaryData?.stateGraph?.states?.forEach((state) { - fileStrategy.commandCreated(WriteSymbolCommand('TODO', + fileStrategy.commandCreated(WriteSymbolCommand( + 'TODO', // 'SYMBOL${state.variation.node.currentContext.tree.UUID}', state.variation.node.name.snakeCase, generationManager.generate(state.variation.node, context), @@ -163,23 +169,24 @@ class BLoCMiddleware extends StateManagementMiddleware { }); // Generate default node's view page - fileStrategy.commandCreated(WriteSymbolCommand( - 'SYMBOL${context.tree.UUID}', - node.name.snakeCase, - generationManager.generate(node, context), + fileStrategy.commandCreated(WriteSymbolCommand('SYMBOL${context.tree.UUID}', + node.name.snakeCase, generationManager.generate(node, context), relativePath: generalName)); /// Creates cubit page context.managerData.addImport(FlutterImport('meta.dart', 'meta')); - context.managerData.addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); + context.managerData + .addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); fileStrategy.commandCreated(WriteSymbolCommand( - context.tree.UUID, - '${generalName}_cubit', - _createBlocPage( - parentState, - node.name, - ), - symbolPath: blocDirectory)); + context.tree.UUID, + '${generalName}_cubit', + _createBlocPage( + parentState, + node.name, + ), + symbolPath: blocDirectory, + ownership: FileOwnership.DEV, + )); return Future.value(null); } diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 713ef0e8..611fdcc2 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -69,7 +69,7 @@ class ProviderMiddleware extends StateManagementMiddleware { $modelName(), child: LayoutBuilder( builder: (context, constraints) { - var widget = ${MiddlewareUtils.generateVariableBody(node)}; + var widget = ${MiddlewareUtils.generateVariableBody(node, context)}; context .read<$modelName>() diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 050f256e..1e64411b 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -4,6 +4,7 @@ import 'package:parabeac_core/generation/generators/middleware/state_management/ import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -96,6 +97,7 @@ class RiverpodMiddleware extends StateManagementMiddleware { parentDirectory, code, symbolPath: fileStrategy.RELATIVE_MODEL_PATH, + ownership: FileOwnership.DEV, ), // Generate default node's view page WriteSymbolCommand(context.tree.UUID, node.name.snakeCase, @@ -106,10 +108,10 @@ class RiverpodMiddleware extends StateManagementMiddleware { // Generate node's states' view pages node.auxiliaryData?.stateGraph?.states?.forEach((state) { fileStrategy.commandCreated(WriteSymbolCommand( - 'TODO', + state.context.tree.UUID, // state.variation.node.currentContext.tree.UUID, state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node, context), + generationManager.generate(state.variation.node, state.context), relativePath: parentDirectory, )); }); diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart index b8ac82c9..fd83a48a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_constant_command.dart @@ -16,7 +16,7 @@ class AddConstantCommand extends FileStructureCommand { /// Adds a constant containing `type`, `name` and `value` to `constants.dart` file @override - Future write(FileStructureStrategy strategy) { + Future write(FileStructureStrategy strategy) async { strategy.appendDataToFile( _addConstant, p.join(strategy.GENERATED_PROJECT_PATH, CONST_DIR_PATH), diff --git a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart index c7009858..e8e5646c 100644 --- a/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart +++ b/lib/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart @@ -9,8 +9,8 @@ class BLoCStateTemplateStrategy extends TemplateStrategy { String abstractClassName; BLoCStateTemplateStrategy({this.isFirst, this.abstractClassName}); @override - String generateTemplate(PBIntermediateNode node, PBGenerationManager manager, - PBContext context, + String generateTemplate( + PBIntermediateNode node, PBGenerationManager manager, PBContext context, {args}) { context.managerData.hasParams = true; context.managerData.hasParams = false; From 6aeafa4dfd9b8484ca865394fdc1bf3b7aae7bde Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Tue, 31 Aug 2021 20:01:48 -0500 Subject: [PATCH 362/404] Hotfix: Pass correct parent to PBSharedParams --- lib/interpret_and_optimize/entities/pb_shared_master_node.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart index 4a684cba..8efe50c7 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_master_node.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_master_node.dart @@ -105,7 +105,7 @@ class PBSharedMasterNode extends PBVisualIntermediateNode ? null : PBSharedParameterProp.createSharedParameter( prop as Map, - parent, + this, tree, ), ) From ec55a4d0d68b6a1f30fe12ad427f1d1f8d1e0a70 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 1 Sep 2021 10:46:43 -0600 Subject: [PATCH 363/404] Sort tabs in order from left to right --- lib/eggs/injected_tab_bar.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index 7ef2146a..e2eb1bd2 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -99,6 +99,9 @@ class PBTabBarGenerator extends PBGenerator { (child) => child.attributeName == InjectedTabBar.BACKGROUND_ATTR_NAME, orElse: () => null); + // Sort tabs from Left to Right + tabs.sort((a, b) => a.frame.left.compareTo(b.frame.left)); + var buffer = StringBuffer(); buffer.write('BottomNavigationBar('); From 8da2cd29f266c4f77ed9b902af1bab80bacd2fd4 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 1 Sep 2021 10:47:02 -0600 Subject: [PATCH 364/404] Do relative sizing only when needed --- .../attribute-helper/pb_size_helper.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index 6c69ca62..090e2fc3 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_attribute_gen_helper.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/inherited_bitmap.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -25,16 +26,15 @@ class PBSizeHelper extends PBAttributesHelper { screenHeight = context.screenFrame.height; } - relativeHeight = - (relativeHeight != null && screenHeight != null && screenHeight > 0.0) - ? relativeHeight / screenHeight - : relativeHeight; - relativeWidth = - (relativeWidth != null && screenWidth != null && screenWidth > 0.0) - ? relativeWidth / screenWidth - : relativeWidth; - if (context.sizingContext == SizingValueContext.ScaleValue) { + relativeHeight = + (relativeHeight != null && screenHeight != null && screenHeight > 0.0) + ? relativeHeight / screenHeight + : relativeHeight; + relativeWidth = + (relativeWidth != null && screenWidth != null && screenWidth > 0.0) + ? relativeWidth / screenWidth + : relativeWidth; var height = source.constraints.fixedHeight != null ? relativeHeight.toStringAsFixed(3) : 'MediaQuery.of(context).size.height * ${relativeHeight.toStringAsFixed(3)}'; From 1237531a7439c139dd72c0ec0a3b12d93d8b400f Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 2 Sep 2021 11:50:18 -0500 Subject: [PATCH 365/404] Refactor on state management graph. This graph allows us to get the default node through a variation. This is useful in order to add necessary imports to the model classes on the screens that need it. --- .../middleware/command_gen_middleware.dart | 7 ++- .../state_management/bloc_middleware.dart | 17 +++-- .../state_management/provider_middleware.dart | 24 +++++-- .../state_management/riverpod_middleware.dart | 14 +++-- .../state_management_middleware.dart | 9 ++- .../state_management/stateful_middleware.dart | 17 +++-- .../utils/middleware_utils.dart | 25 +++++--- .../helpers/element_storage.dart | 5 +- .../helpers/pb_state_management_helper.dart | 16 ++++- .../helpers/pb_state_management_linker.dart | 62 +++++-------------- .../directed_state_graph.dart | 29 +++++++-- .../intermediate_auxillary_data.dart | 9 +-- .../state_management/intermediate_state.dart | 20 ------ .../intermediate_variation.dart | 7 --- 14 files changed, 131 insertions(+), 130 deletions(-) delete mode 100644 lib/interpret_and_optimize/state_management/intermediate_state.dart delete mode 100644 lib/interpret_and_optimize/state_management/intermediate_variation.dart diff --git a/lib/generation/generators/middleware/command_gen_middleware.dart b/lib/generation/generators/middleware/command_gen_middleware.dart index c1675ba8..c7397f77 100644 --- a/lib/generation/generators/middleware/command_gen_middleware.dart +++ b/lib/generation/generators/middleware/command_gen_middleware.dart @@ -9,6 +9,7 @@ import 'package:parabeac_core/generation/generators/value_objects/generation_con import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; import 'package:recase/recase.dart'; @@ -53,7 +54,11 @@ class CommandGenMiddleware extends Middleware tree.name, generationManager.generate(tree.rootNode, context), ); - } else if (tree.rootNode.auxiliaryData.stateGraph.states.isEmpty) { + } else if (PBStateManagementHelper() + .getStateGraphOfNode(tree.rootNode) + ?.states + ?.isEmpty ?? + true) { // TODO: Find a more optimal way to exclude state management nodes command = WriteSymbolCommand( tree.UUID, diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index ae570c3d..ba18eaa0 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -12,7 +12,6 @@ import 'package:parabeac_core/generation/generators/value_objects/template_strat import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; import '../../pb_generation_manager.dart'; @@ -112,9 +111,8 @@ class BLoCMiddleware extends StateManagementMiddleware { var stateBuffer = StringBuffer(); var mapBuffer = StringBuffer(); - node?.auxiliaryData?.stateGraph?.states?.forEach((state) { - states.add(state.variation.node); - }); + var stateGraph = stmgHelper.getStateGraphOfNode(node); + stateGraph?.states?.forEach(states.add); var isFirst = true; states.forEach((element) { @@ -158,12 +156,12 @@ class BLoCMiddleware extends StateManagementMiddleware { )); // Generate node's states' view pages - node.auxiliaryData?.stateGraph?.states?.forEach((state) { + stateGraph?.states?.forEach((state) { fileStrategy.commandCreated(WriteSymbolCommand( 'TODO', // 'SYMBOL${state.variation.node.currentContext.tree.UUID}', - state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node, context), + state.name.snakeCase, + generationManager.generate(state, context), relativePath: generalName, //Generate view files separately )); }); @@ -194,6 +192,7 @@ class BLoCMiddleware extends StateManagementMiddleware { String _makeStateToWidgetFunction(PBIntermediateNode element) { var stateBuffer = StringBuffer(); var importBuffer = StringBuffer(); + var stateGraph = stmgHelper.getStateGraphOfNode(element); var elementName = element.name.substring(0, element.name.lastIndexOf('/')).snakeCase; importBuffer.write("import 'package:flutter/material.dart'; \n"); @@ -202,8 +201,8 @@ class BLoCMiddleware extends StateManagementMiddleware { stateBuffer.write( 'Widget ${elementName.camelCase}StateToWidget( ${elementName.pascalCase}State state, BoxConstraints constraints) {'); - for (var i = 0; i < element.auxiliaryData.stateGraph.states.length; i++) { - var node = element.auxiliaryData.stateGraph.states[i].variation.node; + for (var i = 0; i < stateGraph.states.length; i++) { + var node = stateGraph.states[i]; if (i == 0) { stateBuffer.write(_getStateLogic(node, 'if')); } else { diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 611fdcc2..f82d846c 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -10,6 +10,7 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/provider_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; @@ -51,13 +52,23 @@ class ProviderMiddleware extends StateManagementMiddleware { var managerData = context.managerData; var fileStrategy = configuration.fileStructureStrategy as ProviderFileStructureStrategy; + var elementStorage = ElementStorage(); + if (node is PBSharedInstanceIntermediateNode) { context.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); managerData.addImport(FlutterImport('provider.dart', 'provider')); watcherName = getVariableName(node.name.snakeCase + '_notifier'); - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + /// Get the default node's tree in order to add to dependent of the current tree. + /// + /// This ensures we have the correct modoel imports when generating the tree. + var defaultNodeTreeUUID = elementStorage + .elementToTree[stmgHelper.getStateGraphOfNode(node).defaultNode.UUID]; + var defaultNodeTree = elementStorage.treeUUIDs[defaultNodeTreeUUID]; + + context.tree.addDependent(defaultNodeTree); + PBGenCache().appendToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy, generateModelPath: false)); @@ -124,11 +135,14 @@ class ProviderMiddleware extends StateManagementMiddleware { .add(watcherName); // Generate node's states' view pages - node.auxiliaryData?.stateGraph?.states?.forEach((state) { + var nodeStateGraph = stmgHelper.getStateGraphOfNode(node); + nodeStateGraph?.states?.forEach((state) { + var treeUUID = elementStorage.elementToTree[state.UUID]; + var tree = elementStorage.treeUUIDs[treeUUID]; fileStrategy.commandCreated(WriteSymbolCommand( - state.context.tree.UUID, - state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node, state.context), + tree.UUID, + state.name.snakeCase, + generationManager.generate(state, tree.context), relativePath: parentDirectory, )); }); diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 1e64411b..458e1ce2 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -11,6 +11,7 @@ import 'package:parabeac_core/generation/generators/value_objects/generator_adap import 'package:parabeac_core/generation/generators/value_objects/template_strategy/stateless_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import '../../pb_flutter_generator.dart'; @@ -105,13 +106,18 @@ class RiverpodMiddleware extends StateManagementMiddleware { relativePath: parentDirectory), ].forEach(fileStrategy.commandCreated); + var stateGraph = stmgHelper.getStateGraphOfNode(node); + + var elementStorage = ElementStorage(); // Generate node's states' view pages - node.auxiliaryData?.stateGraph?.states?.forEach((state) { + stateGraph?.states?.forEach((state) { + var treeUUID = elementStorage.elementToTree[node]; + var tree = elementStorage.treeUUIDs[treeUUID]; fileStrategy.commandCreated(WriteSymbolCommand( - state.context.tree.UUID, + tree.UUID, // state.variation.node.currentContext.tree.UUID, - state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node, state.context), + state.name.snakeCase, + generationManager.generate(state, tree.context), relativePath: parentDirectory, )); }); diff --git a/lib/generation/generators/middleware/state_management/state_management_middleware.dart b/lib/generation/generators/middleware/state_management/state_management_middleware.dart index af52da47..2a57cfe6 100644 --- a/lib/generation/generators/middleware/state_management/state_management_middleware.dart +++ b/lib/generation/generators/middleware/state_management/state_management_middleware.dart @@ -5,6 +5,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; /// This [Middleware] is going to focus on the [PBIntermediateNode]s that @@ -14,9 +15,13 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.d /// [PBIntermediateTree], the [StateManagementMiddleware] is going to handle each /// individual [PBIntermediateNode]. abstract class StateManagementMiddleware extends Middleware { + PBStateManagementHelper stmgHelper; + StateManagementMiddleware(PBGenerationManager generationManager, GenerationConfiguration configuration) - : super(generationManager, configuration); + : super(generationManager, configuration) { + stmgHelper = PBStateManagementHelper(); + } /// Forwards all of the nodes of the tree to the [handleStatefulNode], /// the method overridden by the [StateManagementMiddleware]. @@ -59,5 +64,5 @@ abstract class StateManagementMiddleware extends Middleware { /// Checks wheather the [node] contains any states. bool containsState(PBIntermediateNode node) => - node?.auxiliaryData?.stateGraph?.states?.isNotEmpty ?? false; + stmgHelper.getStateGraphOfNode(node)?.states?.isNotEmpty ?? false; } diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 1ddf5e55..06979e73 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -29,7 +29,8 @@ class StatefulMiddleware extends StateManagementMiddleware { } @override - Future handleStatefulNode(PBIntermediateNode node, PBContext context) { + Future handleStatefulNode( + PBIntermediateNode node, PBContext context) { var fileStrategy = configuration.fileStructureStrategy; if (node is PBSharedInstanceIntermediateNode) { @@ -37,18 +38,16 @@ class StatefulMiddleware extends StateManagementMiddleware { return Future.value(node); } - fileStrategy.commandCreated(WriteSymbolCommand( - context.tree.UUID, - node.name.snakeCase, - generationManager.generate(node, context))); + fileStrategy.commandCreated(WriteSymbolCommand(context.tree.UUID, + node.name.snakeCase, generationManager.generate(node, context))); - node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + stmgHelper.getStateGraphOfNode(node).states?.forEach((state) { // state.variation.node.currentContext.tree.data = node.managerData; fileStrategy.commandCreated(WriteSymbolCommand( - 'TODO', + 'TODO', // state.variation.node.currentContext.tree.UUID, - state.variation.node.name.snakeCase, - generationManager.generate(state.variation.node, context))); + state.name.snakeCase, + generationManager.generate(state, context))); }); return Future.value(null); } diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 2812e273..704e8340 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -2,6 +2,7 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; import 'package:recase/recase.dart'; class MiddlewareUtils { @@ -24,23 +25,24 @@ class MiddlewareUtils { } else { stateBuffer.write(MiddlewareUtils.generateVariable(node, context)); } - node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + + var stmgHelper = PBStateManagementHelper(); + + stmgHelper.getStateGraphOfNode(node).states?.forEach((state) { context.tree.generationViewData = context.managerData; - var variationNode = state.variation.node; - if (variationNode is PBSharedMasterNode && - (variationNode.overridableProperties?.isNotEmpty ?? false)) { - variationNode.overridableProperties.forEach((prop) { + if (state is PBSharedMasterNode && + (state.overridableProperties?.isNotEmpty ?? false)) { + state.overridableProperties.forEach((prop) { var friendlyName = prop.propertyName; overrideVars += 'final $friendlyName;'; overrideAttr += 'this.$friendlyName, '; }); - stateBuffer.write(MiddlewareUtils.generateEmptyVariable(variationNode)); + stateBuffer.write(MiddlewareUtils.generateEmptyVariable(state)); stateInitializers.write( - '${variationNode.name.camelCase} = ${MiddlewareUtils.generateVariableBody(variationNode, context)}'); + '${state.name.camelCase} = ${MiddlewareUtils.generateVariableBody(state, context)}'); } else { - stateBuffer - .writeln(MiddlewareUtils.generateVariable(variationNode, context)); + stateBuffer.writeln(MiddlewareUtils.generateVariable(state, context)); } }); @@ -64,7 +66,10 @@ class MiddlewareUtils { static String generateModelChangeNotifier(String defaultStateName, PBGenerationManager manager, PBIntermediateNode node, PBContext context) { // Pass down manager data to states - node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + PBStateManagementHelper() + .getStateGraphOfNode(node) + .states + ?.forEach((state) { // context.tree = node.managerData; }); return ''' diff --git a/lib/interpret_and_optimize/helpers/element_storage.dart b/lib/interpret_and_optimize/helpers/element_storage.dart index c777d2a1..f065ca3d 100644 --- a/lib/interpret_and_optimize/helpers/element_storage.dart +++ b/lib/interpret_and_optimize/helpers/element_storage.dart @@ -1,9 +1,8 @@ -import 'dart:collection'; - import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; class ElementStorage { - static final ElementStorage _elementStorageInstance = ElementStorage._internal(); + static final ElementStorage _elementStorageInstance = + ElementStorage._internal(); /// This [Map] contains the [PBIntermediateNode.UUID] to [PBIntermediateTree.UUID]. /// diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_helper.dart b/lib/interpret_and_optimize/helpers/pb_state_management_helper.dart index 694c8fa3..41e81e80 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_helper.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_helper.dart @@ -1,8 +1,9 @@ +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_linker.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/directed_state_graph.dart'; /// Class that interprets state management nodes class PBStateManagementHelper { @@ -43,4 +44,17 @@ class PBStateManagementHelper { /// Returns true if `name` is a valid state management name bool isValidStateNode(String name) => RegExp(r'^\w*\/(\w*,?\s?)*[\w]$').hasMatch(name); + + /// Returns the [DirectedStateGraph] of `node`. + /// + /// Returns `null` if `node` has no `DirectedStateGraph` + DirectedStateGraph getStateGraphOfNode(PBIntermediateNode node) { + if (isValidStateNode(node.name) && + (node is PBSharedMasterNode || + node is PBSharedInstanceIntermediateNode)) { + var rootNodeName = _getNodeName(node.name); + return linker.getDirectedStateGraphOfName(rootNodeName); + } + return null; + } } diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 71c8ba18..05db20b2 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -1,8 +1,8 @@ - import 'package:parabeac_core/controllers/interpret.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; @@ -10,15 +10,15 @@ import 'package:parabeac_core/interpret_and_optimize/services/pb_alignment_gener import 'package:parabeac_core/interpret_and_optimize/services/pb_layout_generation_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_plugin_control_service.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_symbol_linker_service.dart'; -import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_state.dart'; -import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_variation.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/directed_state_graph.dart'; class PBStateManagementLinker { + ElementStorage elementStorage; Interpret interpret; PBStateManagementLinker._internal() { interpret = Interpret(); - _statemap = {}; stateQueue = []; + elementStorage = ElementStorage(); } static final PBStateManagementLinker _instance = @@ -28,69 +28,41 @@ class PBStateManagementLinker { // Interpret interpret; - Map _statemap; + final Map _rootNameToGraph = {}; List stateQueue; - bool containsElement(String name) => _statemap.containsKey(name); + bool containsElement(String name) => _rootNameToGraph.containsKey(name); /// Returns true if `name` exists in the statemap and it is /// a symbol instance. bool isSymbolInstance(String name) => - _statemap.containsKey(name) && - _statemap[name] is PBSharedInstanceIntermediateNode; + _rootNameToGraph.containsKey(name) && + _rootNameToGraph[name] is PBSharedInstanceIntermediateNode; - /// Adds the `node` variation to the [DirectedStateGraph] of the - /// default [PBIntermediateNode], or sets up `node` as default - /// to receive [IntermediateStates] in its state graph. void processVariation(PBIntermediateNode node, String rootNodeName, PBIntermediateTree tree) async { - // Assign `node` as default + // if `node` is default, create a new graph if (!containsElement(rootNodeName)) { - _statemap[rootNodeName] = node; + _rootNameToGraph[rootNodeName] = DirectedStateGraph(node); } - // Replacing a default node that was an instance node - else if (node is PBSharedMasterNode && - _statemap[rootNodeName] is PBSharedInstanceIntermediateNode) { - var instanceNode = _statemap[rootNodeName]; - - // Transfer states to new default node - instanceNode.auxiliaryData.stateGraph.states - .forEach((state) => node.auxiliaryData.stateGraph.addState(state)); - - // Add old default node as state of new default node - stateQueue.add( - _interpretVariationNode(instanceNode, tree).then((processedNode) { - var intermediateState = IntermediateState( - variation: IntermediateVariation(processedNode), - context: tree.context, - ); - node.auxiliaryData.stateGraph.addState(intermediateState); - })); - // Set new default node - _statemap[rootNodeName] = node; - } - // Add state to default node + // Add variation to default state node else { if (node is PBSharedMasterNode) { var tempSym = PBSymbolStorage().getSharedInstanceNodeBySymbolID(node.SYMBOL_ID); tempSym?.forEach((element) => element.isMasterState = true); } - stateQueue.add(_interpretVariationNode(node, tree).then((processedNode) { - var intermediateState = IntermediateState( - variation: IntermediateVariation(processedNode), - context: tree.context, - ); - _statemap[rootNodeName] - .auxiliaryData - .stateGraph - .addState(intermediateState); - })); + stateQueue.add(_interpretVariationNode(node, tree).then((processedNode) => + _rootNameToGraph[rootNodeName].addVariation(processedNode))); } } + /// Gets the [DirectedStateGraph] of `rootNodeName` or `null` if it does not exist. + DirectedStateGraph getDirectedStateGraphOfName(String rootNodeName) => + _rootNameToGraph[rootNodeName]; + /// Runs the state management [PBIntermediateNode] through /// the necessary interpretation services. Future _interpretVariationNode( diff --git a/lib/interpret_and_optimize/state_management/directed_state_graph.dart b/lib/interpret_and_optimize/state_management/directed_state_graph.dart index 8e4941cb..41ed2515 100644 --- a/lib/interpret_and_optimize/state_management/directed_state_graph.dart +++ b/lib/interpret_and_optimize/state_management/directed_state_graph.dart @@ -1,9 +1,26 @@ -import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_state.dart'; +import 'package:directed_graph/directed_graph.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; -class DirectedStateGraph { - List states = []; +/// [DirectedStateGraph] is used to represent the states of a +/// `default state management node`. +class DirectedStateGraph extends DirectedGraph { - void addState(IntermediateState state) => states.add(state); - void removeState(String variationUuid) => - states.removeWhere((element) => element.variation.UUID == variationUuid); + /// `defaultNode` is considered to be the starting point for this graph. + /// + /// Any other [PBIntermediateNode] that is pointed to by `defaultNode` is considered to be + /// a `variation` of the `defaultNode`. + PBIntermediateNode defaultNode; + + DirectedStateGraph( + this.defaultNode, { + Map, List>> edges, + }) : super(edges); + + /// Adds `variation` as a state of `defaultNode` + void addVariation(PBIntermediateNode variation) => + super.addEdges(defaultNode, [variation]); + + /// Retrieves the states of `defaultNode` + List get states => + super.edges(defaultNode).cast(); } diff --git a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart index c0cf52c1..aba0e99b 100644 --- a/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart +++ b/lib/interpret_and_optimize/state_management/intermediate_auxillary_data.dart @@ -1,15 +1,11 @@ import 'package:parabeac_core/interpret_and_optimize/entities/intermediate_border_info.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; -import 'package:parabeac_core/interpret_and_optimize/state_management/directed_state_graph.dart'; import 'package:json_annotation/json_annotation.dart'; part 'intermediate_auxillary_data.g.dart'; @JsonSerializable(explicitToJson: true) class IntermediateAuxiliaryData { - @JsonKey(ignore: true) - DirectedStateGraph stateGraph; - /// Info relating to the alignment of an element, currently just in a map format. Map alignment; @@ -22,11 +18,8 @@ class IntermediateAuxiliaryData { PBColor color; IntermediateAuxiliaryData({ - this.stateGraph, this.color, - }) { - stateGraph ??= DirectedStateGraph(); - } + }); factory IntermediateAuxiliaryData.fromJson(Map json) => _$IntermediateAuxiliaryDataFromJson(json) diff --git a/lib/interpret_and_optimize/state_management/intermediate_state.dart b/lib/interpret_and_optimize/state_management/intermediate_state.dart deleted file mode 100644 index b7539b43..00000000 --- a/lib/interpret_and_optimize/state_management/intermediate_state.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_variation.dart'; -import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_vertex.dart'; - -class IntermediateState { - IntermediateVariation variation; - List vertexes; - bool isAppState; - - /// Context is added in order for state to know how to generate - /// and inspect `variation's` children. - PBContext context; - - IntermediateState({ - this.variation, - this.vertexes, - this.isAppState, - this.context, - }); -} diff --git a/lib/interpret_and_optimize/state_management/intermediate_variation.dart b/lib/interpret_and_optimize/state_management/intermediate_variation.dart deleted file mode 100644 index 00177b64..00000000 --- a/lib/interpret_and_optimize/state_management/intermediate_variation.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; - -class IntermediateVariation { - String get UUID => node.UUID; - PBIntermediateNode node; - IntermediateVariation(this.node); -} From 89b525b1eca7e86dd4de94b4eb0c933a8c099619 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 2 Sep 2021 16:48:05 -0500 Subject: [PATCH 366/404] Update PBDL ref --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index e48cb9ee..6b34be03 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit e48cb9eed04d233a886bb17955f5f5de1d6c3348 +Subproject commit 6b34be03cafa28a79588d4a3470159f5845e2881 From 5edc62f622153dad99b1da1dfa234d7e2ced7bdc Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Fri, 3 Sep 2021 01:04:12 -0500 Subject: [PATCH 367/404] Fix imports for state management non-default nodes --- .../middleware/command_gen_middleware.dart | 21 +++++++++++++++++++ .../state_management/provider_middleware.dart | 9 +++++++- .../util/pb_generation_view_data.dart | 3 ++- .../helpers/pb_state_management_linker.dart | 15 +++++-------- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/lib/generation/generators/middleware/command_gen_middleware.dart b/lib/generation/generators/middleware/command_gen_middleware.dart index c7397f77..98a47b3d 100644 --- a/lib/generation/generators/middleware/command_gen_middleware.dart +++ b/lib/generation/generators/middleware/command_gen_middleware.dart @@ -7,10 +7,12 @@ import 'package:parabeac_core/generation/generators/value_objects/file_structure import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_platform_orientation_generation_mixin.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_state_management_helper.dart'; import 'package:parabeac_core/interpret_and_optimize/services/pb_platform_orientation_linker_service.dart'; +import 'package:parabeac_core/interpret_and_optimize/state_management/directed_state_graph.dart'; import 'package:recase/recase.dart'; class CommandGenMiddleware extends Middleware @@ -84,6 +86,14 @@ class CommandGenMiddleware extends Middleware var iter = tree.dependentsOn; var addImport = context.managerData.addImport; + /// Check if [tree] has states. If states are present, we need to check + /// each of the states for dependencies. + var smHelper = PBStateManagementHelper(); + var stateGraph = smHelper.getStateGraphOfNode(tree.rootNode); + if (stateGraph != null && tree.rootNode == stateGraph.defaultNode) { + _checkStateGraphImports(stateGraph, packageName); + } + while (iter.moveNext()) { _importProcessor.getFormattedImports( iter.current.UUID, @@ -91,4 +101,15 @@ class CommandGenMiddleware extends Middleware ); } } + + void _checkStateGraphImports(DirectedStateGraph graph, String packageName) { + var elementStorage = ElementStorage(); + graph.states.forEach((state) { + // Get state's graph + var stateTreeUUID = elementStorage.elementToTree[state.UUID]; + var stateTree = elementStorage.treeUUIDs[stateTreeUUID]; + + _addDependencyImports(stateTree, packageName, stateTree.context); + }); + } } diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index f82d846c..53160ccc 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -139,10 +139,17 @@ class ProviderMiddleware extends StateManagementMiddleware { nodeStateGraph?.states?.forEach((state) { var treeUUID = elementStorage.elementToTree[state.UUID]; var tree = elementStorage.treeUUIDs[treeUUID]; + // generate imports for state view + var data = PBGenerationViewData() + ..addImport(FlutterImport('material.dart', 'flutter')); + tree.generationViewData.importsList.forEach(data.addImport); + tree.context.generationManager = + PBFlutterGenerator(ImportHelper(), data: data); + fileStrategy.commandCreated(WriteSymbolCommand( tree.UUID, state.name.snakeCase, - generationManager.generate(state, tree.context), + tree.context.generationManager.generate(state, tree.context), relativePath: parentDirectory, )); }); diff --git a/lib/generation/generators/util/pb_generation_view_data.dart b/lib/generation/generators/util/pb_generation_view_data.dart index 4ea6e13f..178622ec 100644 --- a/lib/generation/generators/util/pb_generation_view_data.dart +++ b/lib/generation/generators/util/pb_generation_view_data.dart @@ -12,7 +12,6 @@ class PBGenerationViewData { bool _isDataLocked = false; bool hasParams = false; - PLATFORM platform; ORIENTATION orientation; @@ -31,6 +30,8 @@ class PBGenerationViewData { ///Imports for the current page Iterator get imports => _imports.iterator; + List get importsList => _imports.toList(); + String get methodVariableStr { var buffer = StringBuffer(); var it = _methodVariables.values.iterator; diff --git a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart index 05db20b2..f63b51d3 100644 --- a/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart +++ b/lib/interpret_and_optimize/helpers/pb_state_management_linker.dart @@ -67,16 +67,11 @@ class PBStateManagementLinker { /// the necessary interpretation services. Future _interpretVariationNode( PBIntermediateNode node, PBIntermediateTree tree) async { - var builder = AITServiceBuilder([PBSymbolLinkerService()]); - - builder.addTransformation((PBContext context, PBIntermediateTree tree) { - return PBPluginControlService() - .convertAndModifyPluginNodeTree(tree, context); - }).addTransformation((PBContext context, PBIntermediateTree tree) { - return PBLayoutGenerationService().extractLayouts(tree, context); - }).addTransformation((PBContext context, PBIntermediateTree tree) { - return PBAlignGenerationService().addAlignmentToLayouts(tree, context); - }); + var builder = AITServiceBuilder([ + PBSymbolLinkerService(), + PBLayoutGenerationService(), + PBAlignGenerationService(), + ]); await builder.build(tree: tree, context: tree.context); return tree.rootNode; } From 748c8cf7877410f23b5f6ac605907c7f3ae08f80 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 3 Sep 2021 12:01:46 -0600 Subject: [PATCH 368/404] Added cases that generate pages and screens if they are set to convert --- .../helpers/pb_project.dart | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_project.dart b/lib/interpret_and_optimize/helpers/pb_project.dart index 7c08db36..2f4ac002 100644 --- a/lib/interpret_and_optimize/helpers/pb_project.dart +++ b/lib/interpret_and_optimize/helpers/pb_project.dart @@ -83,18 +83,27 @@ class PBProject { List> pages) { var trees = []; pages.forEach((page) { - var screens = (page['screens'] as Iterable).map((screen) { - // Generate Intermedite tree - var tree = PBIntermediateTree.fromJson(screen)..name = page['name']; - tree.generationViewData = PBGenerationViewData(); - - if (tree != null) { - PBProject.log.fine( - 'Processed \'${tree.name}\' in page \'${tree.identifier}\' with item type: \'${tree.tree_type}\''); - } - return tree; - }).toList(); - trees.addAll(screens); + // This avoid to generate pages set to not convert + if (page.containsKey('convert') && page['convert']) { + var screens = (page['screens'] as Iterable).map((screen) { + // This avoid to generate screens set to not convert + if (screen.containsKey('convert') && screen['convert']) { + // Generate Intermedite tree + var tree = PBIntermediateTree.fromJson(screen)..name = page['name']; + + tree.generationViewData = PBGenerationViewData(); + + if (tree != null) { + PBProject.log.fine( + 'Processed \'${tree.name}\' in page \'${tree.identifier}\' with item type: \'${tree.tree_type}\''); + } + return tree; + } + }).toList(); + // Remove screens so they do not get added + screens.removeWhere((element) => element == null); + trees.addAll(screens); + } }); return trees; From 20d8bdcc4debd54147a0c9319fa4605baaf9197f Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 3 Sep 2021 14:48:18 -0600 Subject: [PATCH 369/404] Rearreange string formatter --- .../generators/util/pb_input_formatter.dart | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/util/pb_input_formatter.dart b/lib/generation/generators/util/pb_input_formatter.dart index 6744e40f..0a127331 100644 --- a/lib/generation/generators/util/pb_input_formatter.dart +++ b/lib/generation/generators/util/pb_input_formatter.dart @@ -31,13 +31,14 @@ class PBInputFormatter { var result = input; // TODO: set a temporal name result = (result.isEmpty) ? 'tempName' : result; - result = removeFirstDigits(result); + result = result.trim(); var spaceChar = (spaceToUnderscore) ? '_' : ''; result = result.replaceAll(r'[\s\./_+?]+', spaceChar); result = result.replaceAll(RegExp(r'\s+'), spaceChar); - result = (destroyDigits) ? result.replaceAll(RegExp(r'\d+'), '') : result; result = result.replaceAll(' ', '').replaceAll(RegExp(r'[^\s\w]'), ''); + result = removeFirstDigits(result); + result = (destroyDigits) ? result.replaceAll(RegExp(r'\d+'), '') : result; return result; } @@ -54,4 +55,14 @@ class PBInputFormatter { } return target.split(delimeter).last; } + + static String removeFirstSpecials(String str) { + while (str.startsWith(RegExp(r'[^\s\w]')) || + str.startsWith(RegExp(r'^[\d]+'))) { + str = str.startsWith(RegExp(r'^[\d]+')) + ? str.replaceFirstMapped(RegExp(r'^[\d]+'), (e) => '') + : str.replaceFirstMapped(RegExp(r'[^\s\w]'), (e) => ''); + } + return str; + } } From d58472af5c03628312375e423685b464986c89cd Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 3 Sep 2021 14:49:18 -0600 Subject: [PATCH 370/404] Format screen and direcotry names --- .../helpers/pb_intermediate_node_tree.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index e6128524..0e3361d6 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -1,4 +1,5 @@ import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; +import 'package:parabeac_core/generation/generators/util/pb_input_formatter.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_scaffold.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -251,6 +252,9 @@ class PBIntermediateTree extends DirectedGraph { Map toJson() => _$PBIntermediateTreeToJson(this); static PBIntermediateTree fromJson(Map json) { + json['name'] = PBInputFormatter.removeFirstSpecials(json['name']); + json['designNode']['name'] = + PBInputFormatter.removeFirstSpecials(json['designNode']['name']); var tree = _$PBIntermediateTreeFromJson(json); var designNode = PBIntermediateNode.fromJson(json['designNode'], null, tree); From dfb05809d600c1deb988a32a5c11c6b25521a390 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 3 Sep 2021 15:37:54 -0600 Subject: [PATCH 371/404] Removed unused method --- lib/generation/generators/util/pb_input_formatter.dart | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib/generation/generators/util/pb_input_formatter.dart b/lib/generation/generators/util/pb_input_formatter.dart index 0a127331..af3847b9 100644 --- a/lib/generation/generators/util/pb_input_formatter.dart +++ b/lib/generation/generators/util/pb_input_formatter.dart @@ -55,14 +55,4 @@ class PBInputFormatter { } return target.split(delimeter).last; } - - static String removeFirstSpecials(String str) { - while (str.startsWith(RegExp(r'[^\s\w]')) || - str.startsWith(RegExp(r'^[\d]+'))) { - str = str.startsWith(RegExp(r'^[\d]+')) - ? str.replaceFirstMapped(RegExp(r'^[\d]+'), (e) => '') - : str.replaceFirstMapped(RegExp(r'[^\s\w]'), (e) => ''); - } - return str; - } } From 3e998ac1d0e77982fccdfabf513850fe97a49877 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 3 Sep 2021 15:38:06 -0600 Subject: [PATCH 372/404] Format name at json level --- .../helpers/pb_intermediate_node_tree.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 0e3361d6..652f0b3a 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -252,9 +252,9 @@ class PBIntermediateTree extends DirectedGraph { Map toJson() => _$PBIntermediateTreeToJson(this); static PBIntermediateTree fromJson(Map json) { - json['name'] = PBInputFormatter.removeFirstSpecials(json['name']); + json['name'] = PBInputFormatter.formatLabel(json['name']); json['designNode']['name'] = - PBInputFormatter.removeFirstSpecials(json['designNode']['name']); + PBInputFormatter.formatLabel(json['designNode']['name']); var tree = _$PBIntermediateTreeFromJson(json); var designNode = PBIntermediateNode.fromJson(json['designNode'], null, tree); From 61289adee1039ab868c765593e7b655b93dd027c Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 3 Sep 2021 15:38:18 -0600 Subject: [PATCH 373/404] Handle auxiliary data being null --- .../entities/inherited_container.dart | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 98f7362a..8ad000fa 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -39,22 +39,15 @@ class InheritedContainer extends PBVisualIntermediateNode @JsonKey(ignore: true) Map originalRef; - InheritedContainer( - String UUID, - Rectangle3D frame, { - this.originalRef, - String name, - double alignX, - double alignY, - this.isBackgroundVisible = true, - this.prototypeNode, - PBIntermediateConstraints constraints - }) : super( - UUID, - frame, - name, - constraints: constraints - ) { + InheritedContainer(String UUID, Rectangle3D frame, + {this.originalRef, + String name, + double alignX, + double alignY, + this.isBackgroundVisible = true, + this.prototypeNode, + PBIntermediateConstraints constraints}) + : super(UUID, frame, name, constraints: constraints) { generator = PBContainerGenerator(); childrenStrategy = TempChildrenStrategy('child'); //TODO switch alignment to Padding alignment @@ -66,7 +59,7 @@ class InheritedContainer extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) { var container = _$InheritedContainerFromJson(json)..originalRef = json; - container.auxiliaryData.borderInfo.borderRadius = json['fixedRadius']; + container.auxiliaryData?.borderInfo?.borderRadius = json['fixedRadius']; return container; } From 085c397394c467e80f7b64dd5e8b4147158b2abf Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sat, 4 Sep 2021 14:08:27 -0500 Subject: [PATCH 374/404] Fix issues with state management generation and imports. --- lib/configurations/configurations.json | 2 +- .../state_management/bloc_middleware.dart | 37 +++++++++++++---- .../state_management/provider_middleware.dart | 2 +- .../state_management/riverpod_middleware.dart | 29 +++++++++----- .../state_management/stateful_middleware.dart | 40 +++++++++++++++---- 5 files changed, 85 insertions(+), 25 deletions(-) diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index fe22caab..d745b6e1 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -3,7 +3,7 @@ "widgetType": "Stateless", "widgetSpacing": "Expanded", "layoutPrecedence": ["column", "row", "stack"], - "state-management": "provider", + "state-management": "none", "breakpoints": { "mobile": 360, "tablet": 600, diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index ba18eaa0..b7947e8f 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -2,6 +2,7 @@ import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/bloc_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; @@ -11,9 +12,11 @@ import 'package:parabeac_core/generation/generators/value_objects/generator_adap import 'package:parabeac_core/generation/generators/value_objects/template_strategy/bloc_state_template_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; +import '../../pb_flutter_generator.dart'; import '../../pb_generation_manager.dart'; import 'package:path/path.dart' as p; @@ -70,12 +73,23 @@ class BLoCMiddleware extends StateManagementMiddleware { var fileStrategy = configuration.fileStructureStrategy as BLoCFileStructureStrategy; + var elementStorage = ElementStorage(); + /// Incase of SymbolInstance if (node is PBSharedInstanceIntermediateNode) { var generalStateName = node.functionCallName .substring(0, node.functionCallName.lastIndexOf('/')); context.managerData .addImport(FlutterImport('flutter_bloc.dart', 'flutter_bloc')); + + /// Get the default node's tree in order to add to dependent of the current tree. + /// + /// This ensures we have the correct modoel imports when generating the tree. + var defaultNodeTreeUUID = elementStorage + .elementToTree[stmgHelper.getStateGraphOfNode(node).defaultNode.UUID]; + var defaultNodeTree = elementStorage.treeUUIDs[defaultNodeTreeUUID]; + + context.tree.addDependent(defaultNodeTree); if (node.generator is! StringGeneratorAdapter) { var nameWithCubit = '${generalStateName.pascalCase}Cubit'; var nameWithState = '${generalStateName.pascalCase}State'; @@ -157,17 +171,25 @@ class BLoCMiddleware extends StateManagementMiddleware { // Generate node's states' view pages stateGraph?.states?.forEach((state) { + var treeUUID = elementStorage.elementToTree[state.UUID]; + var tree = elementStorage.treeUUIDs[treeUUID]; + // generate imports for state view + var data = PBGenerationViewData() + ..addImport(FlutterImport('material.dart', 'flutter')); + tree.generationViewData.importsList.forEach(data.addImport); + tree.context.generationManager = + PBFlutterGenerator(ImportHelper(), data: data); + fileStrategy.commandCreated(WriteSymbolCommand( - 'TODO', - // 'SYMBOL${state.variation.node.currentContext.tree.UUID}', + tree.UUID, state.name.snakeCase, - generationManager.generate(state, context), - relativePath: generalName, //Generate view files separately + tree.context.generationManager.generate(state, tree.context), + relativePath: generalName, )); }); // Generate default node's view page - fileStrategy.commandCreated(WriteSymbolCommand('SYMBOL${context.tree.UUID}', + fileStrategy.commandCreated(WriteSymbolCommand('${context.tree.UUID}', node.name.snakeCase, generationManager.generate(node, context), relativePath: generalName)); @@ -210,11 +232,12 @@ class BLoCMiddleware extends StateManagementMiddleware { stateBuffer.write(_getStateLogic(node, 'else if')); } } + //TODO: leverage the imports system to generate these imports importBuffer.write( - "import 'package:${MainInfo().projectName}/widgets/$elementName/${node.name.snakeCase}.dart'; \n"); + "import 'package:${MainInfo().projectName}/widgets/$elementName/${node.name.snakeCase}.g.dart'; \n"); } importBuffer.write( - "import 'package:${MainInfo().projectName}/widgets/$elementName/${element.name.snakeCase}.dart'; \n"); + "import 'package:${MainInfo().projectName}/widgets/$elementName/${element.name.snakeCase}.g.dart'; \n"); stateBuffer.write('return ${element.name.pascalCase}(constraints); \n }'); return importBuffer.toString() + stateBuffer.toString(); diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 53160ccc..7e3e82da 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -62,7 +62,7 @@ class ProviderMiddleware extends StateManagementMiddleware { /// Get the default node's tree in order to add to dependent of the current tree. /// - /// This ensures we have the correct modoel imports when generating the tree. + /// This ensures we have the correct model imports when generating the tree. var defaultNodeTreeUUID = elementStorage .elementToTree[stmgHelper.getStateGraphOfNode(node).defaultNode.UUID]; var defaultNodeTree = elementStorage.treeUUIDs[defaultNodeTreeUUID]; diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 458e1ce2..ffa21312 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -53,6 +53,7 @@ class RiverpodMiddleware extends StateManagementMiddleware { var managerData = context.managerData; var fileStrategy = configuration.fileStructureStrategy as RiverpodFileStructureStrategy; + var elementStorage = ElementStorage(); if (node is PBSharedInstanceIntermediateNode) { context.project.genProjectData @@ -70,7 +71,14 @@ class RiverpodMiddleware extends StateManagementMiddleware { managerData.addMethodVariable(watcher); } - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + /// Get the default node's tree in order to add to dependent of the current tree. + /// + /// This ensures we have the correct model imports when generating the tree. + var defaultNodeTreeUUID = elementStorage + .elementToTree[stmgHelper.getStateGraphOfNode(node).defaultNode.UUID]; + var defaultNodeTree = elementStorage.treeUUIDs[defaultNodeTreeUUID]; + + context.tree.addDependent(defaultNodeTree); if (node.generator is! StringGeneratorAdapter) { node.generator = StringGeneratorAdapter(getConsumer( @@ -106,18 +114,21 @@ class RiverpodMiddleware extends StateManagementMiddleware { relativePath: parentDirectory), ].forEach(fileStrategy.commandCreated); - var stateGraph = stmgHelper.getStateGraphOfNode(node); - - var elementStorage = ElementStorage(); - // Generate node's states' view pages - stateGraph?.states?.forEach((state) { - var treeUUID = elementStorage.elementToTree[node]; + var nodeStateGraph = stmgHelper.getStateGraphOfNode(node); + nodeStateGraph?.states?.forEach((state) { + var treeUUID = elementStorage.elementToTree[state.UUID]; var tree = elementStorage.treeUUIDs[treeUUID]; + // generate imports for state view + var data = PBGenerationViewData() + ..addImport(FlutterImport('material.dart', 'flutter')); + tree.generationViewData.importsList.forEach(data.addImport); + tree.context.generationManager = + PBFlutterGenerator(ImportHelper(), data: data); + fileStrategy.commandCreated(WriteSymbolCommand( tree.UUID, - // state.variation.node.currentContext.tree.UUID, state.name.snakeCase, - generationManager.generate(state, tree.context), + tree.context.generationManager.generate(state, tree.context), relativePath: parentDirectory, )); }); diff --git a/lib/generation/generators/middleware/state_management/stateful_middleware.dart b/lib/generation/generators/middleware/state_management/stateful_middleware.dart index 06979e73..94900125 100644 --- a/lib/generation/generators/middleware/state_management/stateful_middleware.dart +++ b/lib/generation/generators/middleware/state_management/stateful_middleware.dart @@ -1,16 +1,21 @@ import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/state_management_middleware.dart'; +import 'package:parabeac_core/generation/generators/pb_flutter_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/element_storage.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import 'package:recase/recase.dart'; import 'package:path/path.dart' as p; +import '../../import_generator.dart'; + class StatefulMiddleware extends StateManagementMiddleware { StatefulMiddleware(PBGenerationManager generationManager, GenerationConfiguration configuration) @@ -32,23 +37,44 @@ class StatefulMiddleware extends StateManagementMiddleware { Future handleStatefulNode( PBIntermediateNode node, PBContext context) { var fileStrategy = configuration.fileStructureStrategy; + var elementStorage = ElementStorage(); if (node is PBSharedInstanceIntermediateNode) { - addImportToCache(node.SYMBOL_ID, getImportPath(node, fileStrategy)); + /// Get the default node's tree in order to add to dependent of the current tree. + /// + /// This ensures we have the correct model imports when generating the tree. + var defaultNodeTreeUUID = elementStorage + .elementToTree[stmgHelper.getStateGraphOfNode(node).defaultNode.UUID]; + var defaultNodeTree = elementStorage.treeUUIDs[defaultNodeTreeUUID]; + + context.tree.addDependent(defaultNodeTree); return Future.value(node); } fileStrategy.commandCreated(WriteSymbolCommand(context.tree.UUID, node.name.snakeCase, generationManager.generate(node, context))); - stmgHelper.getStateGraphOfNode(node).states?.forEach((state) { - // state.variation.node.currentContext.tree.data = node.managerData; + // Generate node's states' view pages + //TODO: Find a way to abstract the process below in order to be used by any middleware + var nodeStateGraph = stmgHelper.getStateGraphOfNode(node); + nodeStateGraph?.states?.forEach((state) { + var treeUUID = elementStorage.elementToTree[state.UUID]; + var tree = elementStorage.treeUUIDs[treeUUID]; + // generate imports for state view + var data = PBGenerationViewData() + ..addImport(FlutterImport('material.dart', 'flutter')); + tree.generationViewData.importsList.forEach(data.addImport); + tree.context.generationManager = + PBFlutterGenerator(ImportHelper(), data: data); + fileStrategy.commandCreated(WriteSymbolCommand( - 'TODO', - // state.variation.node.currentContext.tree.UUID, - state.name.snakeCase, - generationManager.generate(state, context))); + tree.UUID, + state.name.snakeCase, + tree.context.generationManager.generate(state, tree.context), + relativePath: ImportHelper.getName(node.name).snakeCase, + )); }); + return Future.value(null); } } From 31cc3b72329d9af032a667e418a6814e1d8bbd1e Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 7 Sep 2021 13:38:28 -0600 Subject: [PATCH 375/404] Added assets/ directory before images/ for bitmaps --- lib/interpret_and_optimize/entities/pb_shared_instance.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/interpret_and_optimize/entities/pb_shared_instance.dart b/lib/interpret_and_optimize/entities/pb_shared_instance.dart index 249b8ee6..f0bf123b 100644 --- a/lib/interpret_and_optimize/entities/pb_shared_instance.dart +++ b/lib/interpret_and_optimize/entities/pb_shared_instance.dart @@ -106,6 +106,8 @@ class PBSharedInstanceIntermediateNode extends PBVisualIntermediateNode vals.forEach((overrideValue) { if (overrideValue.type == 'stringValue') { overrideValue.value = overrideValue.value.replaceAll('\$', '\\\$'); + } else if (overrideValue.type == 'image') { + overrideValue.value = 'assets/' + overrideValue.value; } }); } From 84dde68c43233e59334f2739ea18575f9cb622c9 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 7 Sep 2021 13:38:52 -0600 Subject: [PATCH 376/404] Give dev the ownership of responsive and orientation builder --- .../commands/orientation_builder_command.dart | 3 +++ .../commands/responsive_layout_builder_command.dart | 2 ++ 2 files changed, 5 insertions(+) diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart index 9fc0f951..8372aaa6 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/orientation_builder_command.dart @@ -2,6 +2,8 @@ import 'package:path/path.dart' as p; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; +import '../file_ownership_policy.dart'; + class OrientationBuilderCommand extends FileStructureCommand { static final DIR_TO_ORIENTATION_BUILDER = 'lib/widgets/'; static final NAME_TO_ORIENTAION_BUILDER = @@ -58,6 +60,7 @@ class OrientationBuilderCommand extends FileStructureCommand { p.join(strategy.GENERATED_PROJECT_PATH, DIR_TO_ORIENTATION_BUILDER), NAME_TO_ORIENTAION_BUILDER, UUID: UUID, + ownership: FileOwnership.DEV, ); } } diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart index 462552e9..24415f95 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/responsive_layout_builder_command.dart @@ -1,4 +1,5 @@ import 'dart:collection'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:path/path.dart' as p; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; @@ -51,6 +52,7 @@ class ResponsiveLayoutBuilderCommand extends FileStructureCommand { p.join(strategy.GENERATED_PROJECT_PATH, DIR_TO_RESPONSIVE_LAYOUT), NAME_TO_RESPONSIVE_LAYOUT, UUID: UUID, + ownership: FileOwnership.DEV, ); } From 9d39648f8b92deb177d725736b6ceba00d326aa8 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 8 Sep 2021 16:12:21 -0600 Subject: [PATCH 377/404] Added a case for appbar to get background color from tree --- lib/eggs/injected_app_bar.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 95ce6b26..717f15f1 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -117,10 +117,13 @@ class PBAppBarGenerator extends PBGenerator { child.attributeName != InjectedAppbar.TRAILING_ATTR_NAME && child.attributeName != InjectedAppbar.BACKGROUND_ATTR_NAME); - if (background != null) { + if (background != null && background.auxiliaryData?.color != null) { // TODO: PBColorGen may need a refactor in order to support `backgroundColor` when inside this tag buffer.write( 'backgroundColor: Color(${background.auxiliaryData?.color?.toString()}),'); + } else { + buffer.write( + 'backgroundColor: Color(${generatorContext.tree.rootNode.auxiliaryData.color.toString()}),'); } if (actions.isNotEmpty) { buffer.write( From aaa1080537b3734149f090a4589c8bca6e9afe62 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 8 Sep 2021 16:12:52 -0600 Subject: [PATCH 378/404] Added injected container for box decoration and added that info through the stack --- .../pb_box_decoration_gen_helper.dart | 3 +- .../entities/layouts/group/frame_group.dart | 47 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart index e047ad8e..e8a5794e 100644 --- a/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_box_decoration_gen_helper.dart @@ -1,5 +1,6 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_attribute_gen_helper.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_container.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -9,7 +10,7 @@ class PBBoxDecorationHelper extends PBAttributesHelper { @override String generate(PBIntermediateNode source, PBContext generatorContext) { - if (source is InheritedContainer) { + if (source is InheritedContainer || source is InjectedContainer) { final buffer = StringBuffer(); buffer.write('decoration: BoxDecoration('); var borderInfo = source.auxiliaryData.borderInfo; diff --git a/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart index 86a97be3..32b0e34a 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart @@ -1,4 +1,6 @@ import 'package:parabeac_core/generation/prototyping/pb_prototype_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/injected_container.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/intermediate_border_info.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/group/group.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/rules/layout_rule.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/exceptions/layout_exception.dart'; @@ -8,6 +10,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_constraints.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_layout_intermediate_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; import 'package:parabeac_core/interpret_and_optimize/state_management/intermediate_auxillary_data.dart'; @@ -34,8 +37,44 @@ class FrameGroup extends Group { @override PBIntermediateNode createIntermediateNode(Map json, - PBIntermediateNode parent, PBIntermediateTree tree) => - _$FrameGroupFromJson(json) - ..mapRawChildren(json, tree) - ..originalRef = json; + PBIntermediateNode parent, PBIntermediateTree tree) { + var tempFrame = _$FrameGroupFromJson(json)..originalRef = json; + + var tempChild = injectAContainer(json, tempFrame.frame); + + if (tempChild != null) { + tree.addEdges(tempFrame, [tempChild]); + } + return tempFrame..mapRawChildren(json, tree); + } + + PBIntermediateNode injectAContainer( + Map json, Rectangle3D parentFrame) { + var tempChild = InjectedContainer( + null, + parentFrame..z = 0, + name: json['name'], + ); + var gateKeeper = false; + if (json['fixedRadius'] != null) { + tempChild.auxiliaryData.borderInfo = + IntermediateBorderInfo(borderRadius: json['fixedRadius']); + tempChild.auxiliaryData.borderInfo.isBorderOutlineVisible = true; + gateKeeper = true; + } + if (json['background'] != null) { + tempChild.auxiliaryData.color = PBColor.fromJson(json['background']); + gateKeeper = true; + } + if (json['style']['borders'][0]['isEnabled']) { + tempChild.auxiliaryData.borderInfo.isBorderOutlineVisible = true; + tempChild.auxiliaryData.borderInfo.color = + PBColor.fromJson(json['style']['borders'][0]['color']); + tempChild.auxiliaryData.borderInfo.thickness = + json['style']['borders'][0]['thickness']; + gateKeeper = true; + } + + return gateKeeper ? tempChild : null; + } } From 9862ec974f0c262aafa8e5ea39b1b371bd4763c9 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 8 Sep 2021 16:13:09 -0600 Subject: [PATCH 379/404] Make sure that the text content is cleanse before writing it --- lib/generation/generators/visual-widgets/pb_text_gen.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/generation/generators/visual-widgets/pb_text_gen.dart b/lib/generation/generators/visual-widgets/pb_text_gen.dart index 207f822f..d67ecd64 100644 --- a/lib/generation/generators/visual-widgets/pb_text_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_text_gen.dart @@ -12,6 +12,8 @@ class PBTextGen extends PBGenerator { @override String generate(PBIntermediateNode source, PBContext context) { if (source is InheritedText) { + var cleanText = + source.text?.replaceAll('\n', ' ')?.replaceAll('\'', '\\\'') ?? ''; context.project.genProjectData .addDependencies('auto_size_text', '^2.1.0'); @@ -29,8 +31,7 @@ class PBTextGen extends PBGenerator { if (textOverride != null) { buffer.write('${textOverride.propertyName} ?? '); } - buffer - .write(('\'${source.text?.replaceAll('\n', ' ') ?? ''}\'') + ',\n'); + buffer.write(('\'$cleanText\'') + ',\n'); } buffer.write('style: '); var styleOverride = OverrideHelper.getProperty(source.UUID, 'textStyle'); From 55e5040c4394613efa32d9339ccffae15f6dc82f Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Thu, 9 Sep 2021 17:44:57 -0500 Subject: [PATCH 380/404] Update pubspec.yaml to version 2.0.0! --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 3ecd4453..447e783c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: parabeac_core description: A starting point for Dart libraries or applications. -version: 1.4.6 +version: 2.0.0 # homepage: https://www.example.com environment: From 3462dfee13b49bfe381249a9620e4c30592dd5d5 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 9 Sep 2021 17:49:44 -0600 Subject: [PATCH 381/404] Only process node if it is visible --- .../helpers/abstract_intermediate_node_factory.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index 4efa0937..ff70dd53 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -45,7 +45,7 @@ class AbstractIntermediateNodeFactory { static dynamic getIntermediateNode(Map json, PBIntermediateNode parent, PBIntermediateTree tree) { var className = json[INTERMEDIATE_TYPE]; - if (className != null) { + if (className != null && json['isVisible']) { for (var candidate in _intermediateNodes) { if (candidate.type == className) { var iNode = candidate.createIntermediateNode(json, parent, tree); From 52d61a0959109ef72628e04926bc3f82db30788b Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 9 Sep 2021 17:49:44 -0600 Subject: [PATCH 382/404] Only process node if it is visible --- .../helpers/abstract_intermediate_node_factory.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart index 4efa0937..60994a68 100644 --- a/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart +++ b/lib/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart @@ -45,7 +45,7 @@ class AbstractIntermediateNodeFactory { static dynamic getIntermediateNode(Map json, PBIntermediateNode parent, PBIntermediateTree tree) { var className = json[INTERMEDIATE_TYPE]; - if (className != null) { + if (className != null && (json['isVisible'] ?? true)) { for (var candidate in _intermediateNodes) { if (candidate.type == className) { var iNode = candidate.createIntermediateNode(json, parent, tree); From ec9398ac99f4ae9db29cfd2c8cdce7af962a85e2 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Sat, 11 Sep 2021 14:58:09 -0500 Subject: [PATCH 383/404] Update PBDL ref --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index 6b34be03..715abe38 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 6b34be03cafa28a79588d4a3470159f5845e2881 +Subproject commit 715abe38a920d0456d65c2e8d89460e2f1cd71ea From 7735665a6790128fd444a4bfb0c02b865c4d7127 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 13 Sep 2021 15:52:00 -0600 Subject: [PATCH 384/404] Changed tab to use label instead of tittle --- lib/eggs/injected_tab_bar.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index e2eb1bd2..a605a2bf 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -118,7 +118,7 @@ class PBTabBarGenerator extends PBGenerator { buffer.write('BottomNavigationBarItem('); var res = context.generationManager.generate(tab, context); buffer.write('icon: $res,'); - buffer.write('title: Text(""),'); + buffer.write('label: "",'); buffer.write('),'); } } catch (e, stackTrace) { From 595016ed8dba6e8c20fe4194e98ac5ef92105900 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 13 Sep 2021 15:52:21 -0600 Subject: [PATCH 385/404] Corrected size generator --- .../generators/attribute-helper/pb_size_helper.dart | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/generation/generators/attribute-helper/pb_size_helper.dart b/lib/generation/generators/attribute-helper/pb_size_helper.dart index 090e2fc3..2111798f 100644 --- a/lib/generation/generators/attribute-helper/pb_size_helper.dart +++ b/lib/generation/generators/attribute-helper/pb_size_helper.dart @@ -35,13 +35,16 @@ class PBSizeHelper extends PBAttributesHelper { (relativeWidth != null && screenWidth != null && screenWidth > 0.0) ? relativeWidth / screenWidth : relativeWidth; - var height = source.constraints.fixedHeight != null - ? relativeHeight.toStringAsFixed(3) + var height = source.constraints.fixedHeight + ? source.frame.height.toStringAsFixed(3) : 'MediaQuery.of(context).size.height * ${relativeHeight.toStringAsFixed(3)}'; - var width = source.constraints.fixedWidth != null - ? relativeWidth.toStringAsFixed(3) + var width = source.constraints.fixedWidth + ? source.frame.width.toStringAsFixed(3) : 'MediaQuery.of(context).size.width * ${relativeWidth.toStringAsFixed(3)}'; + buffer.write('height: $height,'); + buffer.write('width: $width,'); + // buffer.write( // 'constraints: BoxConstraints(maxHeight: ${height}, maxWidth: ${width}),'); } else if (context.sizingContext == SizingValueContext.LayoutBuilderValue) { From 7fc20ae360681b4878fbc7c2555a160b1ea14819 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 13 Sep 2021 15:53:03 -0600 Subject: [PATCH 386/404] Made corrections on .g --- .../entities/layouts/group/base_group.g.dart | 2 -- .../entities/layouts/group/frame_group.dart | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart b/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart index ce884743..8e98cf77 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/base_group.g.dart @@ -18,7 +18,6 @@ BaseGroup _$BaseGroupFromJson(Map json) { : PBIntermediateConstraints.fromJson( json['constraints'] as Map), ) - ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -27,7 +26,6 @@ BaseGroup _$BaseGroupFromJson(Map json) { } Map _$BaseGroupToJson(BaseGroup instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': Rectangle3D.toJson(instance.frame), diff --git a/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart index 32b0e34a..75a991b6 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart @@ -67,6 +67,7 @@ class FrameGroup extends Group { gateKeeper = true; } if (json['style']['borders'][0]['isEnabled']) { + tempChild.auxiliaryData.borderInfo ??= IntermediateBorderInfo(); tempChild.auxiliaryData.borderInfo.isBorderOutlineVisible = true; tempChild.auxiliaryData.borderInfo.color = PBColor.fromJson(json['style']['borders'][0]['color']); From 9dffd2bcfd01a4b14218bca8601bbccfc9647eab Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 13 Sep 2021 15:53:22 -0600 Subject: [PATCH 387/404] Made corrections on .g --- lib/interpret_and_optimize/entities/inherited_oval.g.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/interpret_and_optimize/entities/inherited_oval.g.dart b/lib/interpret_and_optimize/entities/inherited_oval.g.dart index 74da3458..59614801 100644 --- a/lib/interpret_and_optimize/entities/inherited_oval.g.dart +++ b/lib/interpret_and_optimize/entities/inherited_oval.g.dart @@ -18,7 +18,6 @@ InheritedOval _$InheritedOvalFromJson(Map json) { : PBIntermediateConstraints.fromJson( json['constraints'] as Map), ) - ..subsemantic = json['subsemantic'] as String ..auxiliaryData = json['style'] == null ? null : IntermediateAuxiliaryData.fromJson( @@ -28,7 +27,6 @@ InheritedOval _$InheritedOvalFromJson(Map json) { Map _$InheritedOvalToJson(InheritedOval instance) => { - 'subsemantic': instance.subsemantic, 'UUID': instance.UUID, 'constraints': instance.constraints, 'boundaryRectangle': Rectangle3D.toJson(instance.frame), From 37f9c07cf452da7fcea77a3f69826dde2b4d9f4f Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 13 Sep 2021 15:53:39 -0600 Subject: [PATCH 388/404] Added one height to lines --- .../entities/inherited_container.dart | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/interpret_and_optimize/entities/inherited_container.dart b/lib/interpret_and_optimize/entities/inherited_container.dart index 8ad000fa..ec81d034 100644 --- a/lib/interpret_and_optimize/entities/inherited_container.dart +++ b/lib/interpret_and_optimize/entities/inherited_container.dart @@ -11,6 +11,7 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_visual_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_color.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/abstract_intermediate_node_factory.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; @@ -59,7 +60,13 @@ class InheritedContainer extends PBVisualIntermediateNode static PBIntermediateNode fromJson(Map json) { var container = _$InheritedContainerFromJson(json)..originalRef = json; - container.auxiliaryData?.borderInfo?.borderRadius = json['fixedRadius']; + + container.auxiliaryData.borderInfo.borderRadius = json['fixedRadius']; + + if (container.frame.height == 0) { + container.frame = Rectangle3D(container.frame.left, container.frame.top, + container.frame.width, 1.0, container.frame.z); + } return container; } From 204c3e7014776681128d90dd7b93959254a27406 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Mon, 13 Sep 2021 15:53:55 -0600 Subject: [PATCH 389/404] Corrected color fields names --- .../helpers/pb_color.dart | 26 +++++++++---------- .../helpers/pb_color.g.dart | 16 ++++++------ .../edge_adjacent_detection_test.dart | 17 ++++++------ 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_color.dart b/lib/interpret_and_optimize/helpers/pb_color.dart index 55a88b02..3bd77ee8 100644 --- a/lib/interpret_and_optimize/helpers/pb_color.dart +++ b/lib/interpret_and_optimize/helpers/pb_color.dart @@ -6,16 +6,16 @@ part 'pb_color.g.dart'; @JsonSerializable() class PBColor { - num alpha; - num red; - num green; - num blue; + num a; + num r; + num g; + num b; PBColor( - this.alpha, - this.red, - this.green, - this.blue, + this.a, + this.r, + this.g, + this.b, ); factory PBColor.fromJson(Map json) => @@ -31,10 +31,10 @@ class ColorUtils { static String toHex(PBColor color) { if (color != null) { int a, r, g, b; - a = ((color.alpha ?? 0) * 255).round(); - r = ((color.red ?? 0) * 255).round(); - g = ((color.green ?? 0) * 255).round(); - b = ((color.blue ?? 0) * 255).round(); + a = ((color.a ?? 0) * 255).round(); + r = ((color.r ?? 0) * 255).round(); + g = ((color.g ?? 0) * 255).round(); + b = ((color.b ?? 0) * 255).round(); return '0x' + HEX.encode([a, r, g, b]); } else { return '0x' + HEX.encode([0, 0, 0, 0]); @@ -53,7 +53,7 @@ class ColorUtils { return null; } - /// Returns a json representation of color assuming we receive a PBSL `style` in json format + /// Returns a json representation of color assuming we receive a PBDL `style` in json format static PBColor pbColorFromJsonFills(List> json) { var fills = IndexWalker(json).value; diff --git a/lib/interpret_and_optimize/helpers/pb_color.g.dart b/lib/interpret_and_optimize/helpers/pb_color.g.dart index 752da148..78ff495b 100644 --- a/lib/interpret_and_optimize/helpers/pb_color.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_color.g.dart @@ -8,16 +8,16 @@ part of 'pb_color.dart'; PBColor _$PBColorFromJson(Map json) { return PBColor( - json['alpha'] as num, - json['red'] as num, - json['green'] as num, - json['blue'] as num, + json['a'] as num, + json['r'] as num, + json['g'] as num, + json['b'] as num, ); } Map _$PBColorToJson(PBColor instance) => { - 'alpha': instance.alpha, - 'red': instance.red, - 'green': instance.green, - 'blue': instance.blue, + 'a': instance.a, + 'r': instance.r, + 'g': instance.g, + 'b': instance.b, }; diff --git a/test/lib/input_services/edge_adjacent_detection_test.dart b/test/lib/input_services/edge_adjacent_detection_test.dart index 7cfe5093..ea623e3e 100644 --- a/test/lib/input_services/edge_adjacent_detection_test.dart +++ b/test/lib/input_services/edge_adjacent_detection_test.dart @@ -46,10 +46,10 @@ void main() { borders: [ Border( color: Color( - alpha: 1, - red: 1, - green: 1, - blue: 1, + a: 1, + r: 1, + g: 1, + b: 1, ), ), ], @@ -90,10 +90,10 @@ void main() { borders: [ Border( color: Color( - alpha: 1, - red: 1, - green: 1, - blue: 1, + a: 1, + r: 1, + g: 1, + b: 1, ), ), ], @@ -133,7 +133,6 @@ void main() { when(sketchNode.UUID).thenReturn(''); shapePath = InheritedShapePath(sketchNode, 'testName', currentContext: context); - }); test('Detecting Shape', () { From 2ece3a60243431c7709e8ecf637dc8aa15917eca Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Tue, 14 Sep 2021 10:50:00 -0500 Subject: [PATCH 390/404] Improve speed when generating PBDL This is done by simply exiting immediately after exporting the PBDL to not perform redundant tasks --- lib/main.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/main.dart b/lib/main.dart index 5cf7c309..32581f1f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -118,6 +118,11 @@ ${parser.usage} ); var pbdl = await pbdlService.callPBDL(processInfo); var pbProject = PBProject.fromJson(pbdl.toJson()); + // Exit if only generating PBDL + if (MainInfo().exportPBDL) { + exitCode = 0; + return; + } pbProject.projectAbsPath = p.join(processInfo.outputPath, processInfo.projectName); From 82b996b49ca96983d1f750c2ce1b5d12a158b3b4 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Tue, 14 Sep 2021 17:51:26 -0600 Subject: [PATCH 391/404] Removed wrapOnIconButton for now --- lib/eggs/injected_app_bar.dart | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 717f15f1..2ddcbd67 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -130,7 +130,7 @@ class PBAppBarGenerator extends PBGenerator { '${InjectedAppbar.TRAILING_ATTR_NAME}: ${_getActions(actions, generatorContext)},'); } children.forEach((child) => buffer.write( - '${child.attributeName}: ${_wrapOnIconButton(child.generator.generate(child, generatorContext))},')); + '${child.attributeName}: ${child.generator.generate(child, generatorContext)},')); buffer.write(')'); return buffer.toString(); @@ -142,21 +142,21 @@ class PBAppBarGenerator extends PBGenerator { var buffer = StringBuffer(); buffer.write('['); - actions.forEach((action) => buffer.write( - '${_wrapOnIconButton(action.generator.generate(action, context))},')); + actions.forEach((action) => + buffer.write('${action.generator.generate(action, context)},')); buffer.write(']'); return buffer.toString(); } - String _wrapOnIconButton(String body) { - return ''' - IconButton( - icon: $body, - onPressed: () { - // TODO: Fill action - } - ) - '''; - } + // String _wrapOnIconButton(String body) { + // return ''' + // IconButton( + // icon: $body, + // onPressed: () { + // // TODO: Fill action + // } + // ) + // '''; + // } } From d9d3d88246a518a85eca8366d0d11c05af487601 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 15 Sep 2021 10:20:52 -0500 Subject: [PATCH 392/404] Update pbdl ref --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index 715abe38..cc035938 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 715abe38a920d0456d65c2e8d89460e2f1cd71ea +Subproject commit cc03593861f29a471ed875857d4448eb47a5a5dc From 62e77d7c58a80fbb281be791eca206a3f9175ef7 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 15 Sep 2021 11:25:07 -0500 Subject: [PATCH 393/404] Update pbdl ref --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index cc035938..df93174c 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit cc03593861f29a471ed875857d4448eb47a5a5dc +Subproject commit df93174c285f773a7922c66abb58d5a4db75d071 From d4a990433aff04304ce0b42f694a5d76da51b380 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 15 Sep 2021 11:25:07 -0500 Subject: [PATCH 394/404] Update pbdl ref --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index cc035938..74a7b3bb 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit cc03593861f29a471ed875857d4448eb47a5a5dc +Subproject commit 74a7b3bb877a284eff312cbb873ad74be5674378 From 1e644622c0a737c3f56fc1f2a9950751773ce4a4 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 15 Sep 2021 16:02:09 -0600 Subject: [PATCH 395/404] Use styles --- .../entities/layouts/group/frame_group.dart | 11 ++++++----- pbdl | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart index 75a991b6..39c4c1f9 100644 --- a/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart +++ b/lib/interpret_and_optimize/entities/layouts/group/frame_group.dart @@ -56,14 +56,15 @@ class FrameGroup extends Group { name: json['name'], ); var gateKeeper = false; - if (json['fixedRadius'] != null) { - tempChild.auxiliaryData.borderInfo = - IntermediateBorderInfo(borderRadius: json['fixedRadius']); + if (json['style']['borderOptions']['cornerRadius'] != null) { + tempChild.auxiliaryData.borderInfo = IntermediateBorderInfo( + borderRadius: json['style']['borderOptions']['cornerRadius']); tempChild.auxiliaryData.borderInfo.isBorderOutlineVisible = true; gateKeeper = true; } - if (json['background'] != null) { - tempChild.auxiliaryData.color = PBColor.fromJson(json['background']); + if (json['style']['backgroundColor'] != null) { + tempChild.auxiliaryData.color = + PBColor.fromJson(json['style']['backgroundColor']); gateKeeper = true; } if (json['style']['borders'][0]['isEnabled']) { diff --git a/pbdl b/pbdl index 6b34be03..44e03a5a 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 6b34be03cafa28a79588d4a3470159f5845e2881 +Subproject commit 44e03a5a241277e63beb8ce2b40d54e4a964f6b9 From 477a0922bebeec48b51f471eda49b0551a3e1d5f Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Fri, 17 Sep 2021 12:08:49 -0600 Subject: [PATCH 396/404] Use title flag so file names get processed correctly --- .../helpers/pb_intermediate_node_tree.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index 652f0b3a..2dae3fed 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -252,9 +252,9 @@ class PBIntermediateTree extends DirectedGraph { Map toJson() => _$PBIntermediateTreeToJson(this); static PBIntermediateTree fromJson(Map json) { - json['name'] = PBInputFormatter.formatLabel(json['name']); + json['name'] = PBInputFormatter.formatLabel(json['name'], isTitle: true); json['designNode']['name'] = - PBInputFormatter.formatLabel(json['designNode']['name']); + PBInputFormatter.formatLabel(json['designNode']['name'], isTitle: true); var tree = _$PBIntermediateTreeFromJson(json); var designNode = PBIntermediateNode.fromJson(json['designNode'], null, tree); From 3a4dad012680f0296c163ddc134256af1704f059 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Tue, 21 Sep 2021 15:55:23 -0600 Subject: [PATCH 397/404] Update PBDL ref --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index 715abe38..9192239e 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 715abe38a920d0456d65c2e8d89460e2f1cd71ea +Subproject commit 9192239ede9734b506429b4eeb5de6fb2137caaa From ee96c17a3f9109def3d60946add84a8113cb7534 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 22 Sep 2021 16:13:11 -0600 Subject: [PATCH 398/404] Put appbar on controllers directory for output --- lib/eggs/injected_app_bar.dart | 63 ++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/lib/eggs/injected_app_bar.dart b/lib/eggs/injected_app_bar.dart index 2ddcbd67..a733e022 100644 --- a/lib/eggs/injected_app_bar.dart +++ b/lib/eggs/injected_app_bar.dart @@ -1,13 +1,17 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_color_gen_helper.dart'; +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; -import 'dart:math'; +import 'package:recase/recase.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:uuid/uuid.dart'; class InjectedAppbar extends PBEgg implements PBInjectedIntermediate { @override @@ -133,10 +137,63 @@ class PBAppBarGenerator extends PBGenerator { '${child.attributeName}: ${child.generator.generate(child, generatorContext)},')); buffer.write(')'); - return buffer.toString(); + + var className = source.parent.name + 'Appbar'; + + // TODO: correct import + generatorContext.managerData.addImport(FlutterImport( + 'controller/${className.snakeCase}.dart', + MainInfo().projectName, + )); + + generatorContext + .configuration.generationConfiguration.fileStructureStrategy + .commandCreated(WriteSymbolCommand( + Uuid().v4(), + className.snakeCase, + appBarBody(className, buffer.toString(), + generatorContext.managerData.importsList), + relativePath: 'controller', + symbolPath: 'lib', + ownership: FileOwnership.DEV, + )); + + return '$className()'; } } + String appBarBody( + String className, String body, List importsList) { + var imports = ''; + + importsList.forEach((import) { + if (import.package != MainInfo().projectName) { + imports += import.toString() + '\n'; + } + }); + return ''' + $imports + + class $className extends StatefulWidget implements PreferredSizeWidget{ + final Widget child; + $className({Key key, this.child}) : super (key: key); + + @override + _${className}State createState() => _${className}State(); + + @override + Size get preferredSize => Size.fromHeight(AppBar().preferredSize.height); + } + + class _${className}State extends State<$className> { + @override + Widget build(BuildContext context){ + return $body; + } + } + '''; + } + /// Returns list ot `actions` as individual [PBIntermediateNodes] String _getActions(Iterable actions, PBContext context) { var buffer = StringBuffer(); From 0b49f9ddfe0966a7e16bed1fdea0b341758d3a3f Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 22 Sep 2021 16:13:26 -0600 Subject: [PATCH 399/404] Put tabbar on controllers directory for output --- lib/eggs/injected_tab_bar.dart | 51 ++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/lib/eggs/injected_tab_bar.dart b/lib/eggs/injected_tab_bar.dart index a605a2bf..ef553406 100644 --- a/lib/eggs/injected_tab_bar.dart +++ b/lib/eggs/injected_tab_bar.dart @@ -1,14 +1,18 @@ import 'package:parabeac_core/controllers/main_info.dart'; - +import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/generation/generators/plugins/pb_plugin_node.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/file_ownership_policy.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/interfaces/pb_injected_intermediate.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/align_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/child_strategy.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; -import 'dart:math'; +import 'package:recase/recase.dart'; + +import 'package:uuid/uuid.dart'; class InjectedTabBar extends PBEgg implements PBInjectedIntermediate { @override @@ -130,7 +134,48 @@ class PBTabBarGenerator extends PBGenerator { } buffer.write('],'); buffer.write(')'); - return buffer.toString(); + + var className = source.parent.name + 'Tabbar'; + + // TODO: correct import + context.managerData.addImport(FlutterImport( + 'controller/${className.snakeCase}.dart', + MainInfo().projectName, + )); + + context.configuration.generationConfiguration.fileStructureStrategy + .commandCreated(WriteSymbolCommand( + Uuid().v4(), + className.snakeCase, + tabBarBody(className, buffer.toString()), + relativePath: 'controller', + symbolPath: 'lib', + ownership: FileOwnership.DEV, + )); + + return '$className()'; } } + + String tabBarBody(String className, String body) { + return ''' + import 'package:flutter/material.dart'; + + class $className extends StatefulWidget { + final Widget child; + $className({Key key, this.child}) : super (key: key); + + @override + _${className}State createState() => _${className}State(); + + } + + class _${className}State extends State<$className> { + @override + Widget build(BuildContext context){ + return $body; + } + } + '''; + } } From b96b9ee0866a2620ca8f898a7e69e363d81e13c4 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 22 Sep 2021 16:13:50 -0600 Subject: [PATCH 400/404] WIP, wrap stack on a container if it comes from an appbar --- .../generators/layouts/pb_stack_gen.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/generation/generators/layouts/pb_stack_gen.dart b/lib/generation/generators/layouts/pb_stack_gen.dart index 8cd9d733..9c6933dc 100644 --- a/lib/generation/generators/layouts/pb_stack_gen.dart +++ b/lib/generation/generators/layouts/pb_stack_gen.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/eggs/injected_app_bar.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/layouts/stack.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; @@ -11,6 +12,7 @@ class PBStackGenerator extends PBGenerator { if (source is PBIntermediateStackLayout) { var children = context.tree.childrenOf(source); var buffer = StringBuffer(); + buffer.write('Stack('); if (children.isNotEmpty) { buffer.write('\nchildren: ['); @@ -24,8 +26,21 @@ class PBStackGenerator extends PBGenerator { buffer.write(']'); buffer.write(')'); } + if (source.parent is InjectedAppbar) { + return containerWrapper(buffer.toString(), source); + } return buffer.toString(); } return ''; } + + String containerWrapper(String body, PBIntermediateNode source) { + return ''' + Container( + height: ${source.frame.height}, + width: ${source.frame.width}, + child: $body + ) + '''; + } } From ab95031dbc303aa9b6118c8c2f4847e0064b667b Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 22 Sep 2021 16:33:05 -0600 Subject: [PATCH 401/404] Updated PBDL --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index 44e03a5a..9192239e 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 44e03a5a241277e63beb8ce2b40d54e4a964f6b9 +Subproject commit 9192239ede9734b506429b4eeb5de6fb2137caaa From f9a454733bdeedaa9cd06e2b1a38cf23213532d8 Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Wed, 22 Sep 2021 16:33:40 -0600 Subject: [PATCH 402/404] Updated PBDL --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index 44e03a5a..9192239e 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 44e03a5a241277e63beb8ce2b40d54e4a964f6b9 +Subproject commit 9192239ede9734b506429b4eeb5de6fb2137caaa From a0c1afddb616e1f5eb831c840138d0a67e6699c7 Mon Sep 17 00:00:00 2001 From: Ivan <42812006+ivan-015@users.noreply.github.com> Date: Wed, 22 Sep 2021 19:31:27 -0600 Subject: [PATCH 403/404] PBDL fix asset uploading on azure --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index 9192239e..eb347fb0 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 9192239ede9734b506429b4eeb5de6fb2137caaa +Subproject commit eb347fb0ad5caf58c6d103c46d6548d06c3f7600 From 196948f4a5d1a1ccc329fe930e063801d6f1179f Mon Sep 17 00:00:00 2001 From: Bryan Figueroa Date: Thu, 23 Sep 2021 13:02:36 -0600 Subject: [PATCH 404/404] Updated PBDL --- pbdl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pbdl b/pbdl index eb347fb0..9192239e 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit eb347fb0ad5caf58c6d103c46d6548d06c3f7600 +Subproject commit 9192239ede9734b506429b4eeb5de6fb2137caaa